📄 485_0103.c
字号:
/****************************************************************************************************
uPD78F0881 Uart61 transmit/Receive programme module
uart61 test programme module
manipulate: send several byte data by computer Com tools.
MCU when receive these data,it will send back 0x01,0x02,0x03,0x04 to computer.
*****************************************************************************************************/
#pragma SFR
#pragma EI
#pragma DI
#pragma NOP
#pragma interrupt INTSR61 Uart_INTSR61 RB1
#pragma interrupt INTTM50 Timer_INTTM50 RB2
#include "Uart61.h"
void main(void);
callt void Uart61_Init( void );
callt void UartSend_Byte( uchar ch );
callt void Uart_Send( uchar* txbuf, uchar txnum );
uchar try[4]={0x01,0x02,0x03,0x04};
uchar Uart_Rx[20];
uchar pointer = 0;
bit Uart_Rx_Flag; //recevie ok
unsigned long int L;
//CRC
unsigned char CRC_L,CRC_H,CRC_i,CRC_DATA;
void hdwinit( void ) //PM == 0 output
{
DI();
IMS = MEMORY_IMS_SET;
IXS = MEMORY_IXS_SET;
// Clock operation port mode (OSCCTL register)
AMPH = 0; // select the external Clock frequency range(4MHz < fXH <= 10MHz)
EXCLK = 0; //select the externa High-speed system clock operation mode(fX or fEXCLK or STOP)
OSCSEL = 1; // External resonator connected to fX1 and fX2 input
EXCLKS = 0; //(fXT or fEXCLKS or STOP)
OSCSELS = 0; // XT1 stop working
// (permit) High-speed input clock operating (X1)
MOC = 0x00;
// 00000000 = 0x00
// |------- High-speed input clock operation
// |------- --------------------------------
// |------- fXH input clock | External clock input
// |------- ----------------------------+-------------------------
// 0 -------- fXH input clock oscillating | External clock operating
// 1 -------- fXH input clock stopped | External clock stopped
// Check Oscillation stabilization time status
//waiting for the X1 clock oscillation stabilization time
//--------------------------------------------
// The necessary oscillation stabilization time must be known beforehand.
// Pls. refer to the DS or UM of the oscillator manufacturer.
while(OSTC < 0x1f) // Wait until fXH clock stabilization
{ // time has been elapsed
//----------------------------------------------------------
// During X1 oscillation stabilization time status check
// some other initializations, e.g. ports, can be done,
// dependent on the needed X1 oscillation stabilization time
// 102.4祍...3.28ms @ 20MHz
//----------------------------------------------------------
NOP();
}
//Oscillation stabilization time after STOP mode release
//The wait time set by OSTS is valid only after the STOP mode is released with the X1 clock selected as the CPU clock.
OSTS = 0x01; // 512us@4MHz wait after STOP mode release (RESET value)
// 00000101 = 0x05
// -----||| Osc. stabilization time
// -----||| -----------------------
// -----001 - 2^11/fx
// -----010 - 2^13/fx
// -----011 - 2^14/fx
// -----100 - 2^15/fx
// -----101 - 2^16/fx
// -----other settings prohibited
//This register is used to select the CPU clock and the division ratio
//---------------------------------------------
PCC = 0x00; // Use high speed mode fCPU = 4MHz
// 00000000 = 0x00
// -----||| CPU clock selection fCPU
// -----||| ------------------------
// -----000 - fx
// -----001 - fx/2
// -----010 - fx/2^2
// -----011 - fx/2^3
// -----100 - fx/2^4
// -----other settings prohibited
// selects the main system clock supplied to CPU clock and clock supplied to peripheral hardware clock.
//-----------------------------------------------------------------
// The maximum time required to switch between ring oscillator clock and
// fXH clock is 2 clocks
// fXH clock supplied to the peripherals
XSEL = 1;
do
{
MCM0 = 1; // fXH clock supplied to CPU
// 00000001 = 0x01
// -----||| CPU clock status
// -----||| ----------------
// -----||0 - Operates with ring oscillator clock
// -----||1 - Operates with X1 input clock
// -----||
// -----|| Selection of clock supplied to CPU and peripherals
// -----|| --------------------------------------------------
// -----00 -- fCPU = fRH / fPRS = fRH
// -----01 -- fCPU = fRH / fPRS = fRH
// -----10 -- fCPU = fRH / fPRS = fXH
// -----11 fCPU = fXH / fPRS = fXH <---
// |
// +---- XSEL
}
while(MCS != 1); // Check if CPU operates with fXH clock( bit MCS IS read-only)
// If no => Retry to switch CPU clock
// If yes => continue
// Switch off the high-speed and the low-speed Ring-OSC
//-----------------------------------------------------
// select the operation mode of internal oscillator (all stop)
RCM = 0x01; // High-speed Ring-OSC oscillating
// High-speed Ring-OSC low accuracy (stop)
// Low-speed Ring-OSC oscillating (stop)
// 00000000 = 0x00
// |-----|| High-speed Ring-OSC operation
// |-----|| -----------------------------
// |-----|0 - High-speed Ring-OSC oscillating
// |-----|1 - High-speed Ring-OSC stopped
// |-----|
// |-----| Low-speed Ring-OSC operation
// |-----| ----------------------------
// |-----0 -- Low-speed Ring-OSC oscillating
// |-----1 -- Low-speed Ring-OSC stopped
// |
// | High-speed Ring-OSC accuracy status
// | -----------------------------------
// 0 -------- High-speed Ring-OSC low accuracy
// 1 -------- High-speed Ring-OSC high accuracy
EI();
}
void Lvi_Init( void )
{
LVIMK = 1; //disable LVI interrupt
LVISEL = 0; //Detect level of supply voltage
LVIS = 0X02; //detection voltage level:3.93V
//LVIIF = 0;
//LVIMK = 0;
//LVIPR = 1;
LVIMD = 0; //generates intenal reset when the level is detected
LVION = 1; //enable LVI operation
}
//Init receive enable,transmit disable
callt void Uart61_Init( void )
{
PM1.0 = 0; //output TX
P1.0 = 1; /* port setting in transmit mode */
PM1.1 = 1; //input RX /* port setting in receive mode */
PU1.1 = 1; //on-chip pull-up resistor connected
ASIM61 = 0; //TXE61) and bit 5 (RXE61) of the ASIM61 register = 0 when rewriting the MDL671 to MDL601 bits.
/* baudrate selection = 9600 */
CKSR61 = 0x00; //4MHZ 2M
BRGC61 = 0xd0; // BAUD=2M/0xd0
ASIM61 = 0x04; /* data length 8 bits;stop length 1 bits;Does not output parity bit mode */
ASICL61.1 = 1; /* LSB first transfer */
ASICL61.0 = 0; /* normal output of TxD61 */
//interrupt setting
STMK61 = 1; /* transfer end interrupt disable */
STIF61 = 0;
SRIF61 = 0; /* receive end interrupt enable */
SRMK61 = 0; //0 Interrupt servicing enabled
SREIF61 = 0;
SREMK61 = 1; /* error interrupt disable */
SRPR61 = 0; /* interrupt high */
SREPR61 = 0; /* interrupt high */
//open when need
POWER61 = 1;
RXE61 = 1; // Receive enable
TXE61 = 0; /* transmit disable */
}
void Motor_Init(void)
{
PM0.0=0;P0.0=0; //Up rotation initialize
PM0.1=0;P0.1=0; //Down rotation initialize
PM3.0=0;P3.0=0; //Left rotation initialize
PM3.3=0;P3.3=0; //Right rotation initialize
}
callt void UartSend_Byte( uchar ch )
{
TXB61 = ch;
while(!STIF61);
STIF61 = 0;
}
/* Data transfer */
//enable send,disable receive(when send data),after send enable receive
callt void Uart_Send( uchar* txbuf, uchar txnum )
{
POWER61 = 1;
TXE61 = 1;//enable send,disable receive
RXE61 = 0;
//Delay( 2 ); //delay 1ms,wait until hardware work stably
if( txnum < 1)
{
return;
}
else
{
do
{
UartSend_Byte( *txbuf++ );
txnum--;
}while( txnum != 0 );
}
//Delay( 2 ); //delay 1ms,wait until the last byte was transmited
TXE61 = 0;
RXE61 = 1; //disable send,enable receive
}
void Timer50_Init( void )
{
TMIF50 = 0; //clear the Timer50 interrupt flag
TMMK50 = 0; /*enable interrupt INTTM50*/
TMPR50 = 0; /*interrupt INTTM50 High*/
//Timer clock selection register
TCL50 = 0x06; /*TM50 count clock=fprs/2^8*/
//8-bit timer compare register
CR50 = 0xeb; /*interval time*fprs/2^8-1,interval time = 15ms*/
//8-bit timer mode control register
TMC50 = 0x00; /*clears and starts on match between TM50 and CR50;output disabled*/
//TCE50 = 1; //Count operation start
}
void CRC(void) //CALCULATE:THE CRC INPUT:CRC_L,CRC_H,CRC_DATA, OUTPUT:CRC_L,CRC_H
{
CRC_L=CRC_L^CRC_DATA;
for(CRC_i=0;CRC_i<8;CRC_i++)
{ if(CRC_L%2)
{ CRC_L=CRC_L>>1; // /2;
if(CRC_H%2)
{
CRC_H=CRC_H>>1; // /2;
CRC_L=CRC_L|0x80;
}
else CRC_H=CRC_H>>1; // /2;
CRC_L=CRC_L^0x01;
CRC_H=CRC_H^0xA0;
}
else
{
CRC_L=CRC_L>>1; // /2;
if(CRC_H%2)
{
CRC_H=CRC_H>>1; // /2;
CRC_L=CRC_L|0x80;
}
else CRC_H=CRC_H>>1; // /2;
}
}
}
void Check(void)
{ unsigned char i;
CRC_L=0xFF;CRC_H=0xFF; //Set the initial value of the verify
for(i=0;i<=1;i++)
{CRC_DATA=Uart_Rx[i];
CRC();
if(Uart_Rx[i+1]!=CRC_L) return;
if(Uart_Rx[i+2]!=CRC_H) return;
}
}
__interrupt void Timer_INTTM50( void )//interval between Uart receive byte overflow 15ms
{
EI();
TCE50 = 0; //disable Timer50
Uart_Rx_Flag = 1;
//disable UART61
RXE61 = 0;
TXE61 = 0;
POWER61 = 0; //disable UART61
}
/* UART61 receive end interrupt handler */
__interrupt void Uart_INTSR61( void )
{
uchar tmp,ErrUart61;
//interrupt will close when go into interrupt handler programmes, so open again is necessary
EI();
//restart Timer50
TCE50 = 0; //clear the Timer
TCE50 = 1; //Count operation start
ErrUart61 = ASIS61; //will be cleared when read.if is not cleared,uart61 will not receive new data to RXB61
tmp = RXB61;
Uart_Rx[pointer] = tmp;
pointer ++;
Check();
if(pointer> Uart_Rx_Len) //over the size of Uart_Rx[]
{
//disable UART61
pointer = 0;
RXE61 = 0;
TXE61 = 0;
POWER61 = 0;
Uart_Rx_Flag = 1;
}
}
callt void System_Init()
{
Lvi_Init();
Timer50_Init();
Uart61_Init();
Motor_Init();
}
void Motor_Control(void)
{ if(Uart_Rx[0x0]==0x01)
{//Up Control
P0.0=1;
L=2000;
while(L--) {;}
P0.0=0;
}
else if(Uart_Rx[0x0]==0x02)
{ //Down control
P0.1=1;
L=2000;
while(L--) {;}
P0.1=0;
}
else if(Uart_Rx[0x0]==0x03)
{ //Left control
P3.0=1;
L=2000;
while(L--) {;}
P3.0=0;
}
else if(Uart_Rx[0x0]==0x04)
{ //Right control
P3.3=1;
L=2000;
while(L--) {;}
P3.3=0;
}
else
{
NOP();
}
}
void main(void)
{
DI();
System_Init();
EI();
PM4.0=0;
P4.0 = 0;
//TCE50 = 1;
while(1)
{
WDTE = 0xac; //clear the WDT
if(Uart_Rx_Flag)
{
pointer = 0;
Uart_Rx_Flag = 0;
P4.0 = 1;
Uart_Send(Uart_Rx,4);
P4.0=0;
Motor_Control();
}
}
NOP();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -