📄 hwdevice111.c
字号:
#include <string.h>
#include <stdio.h>
#include "ez328_c.h"
#include <device.h>
#include <car_set.h>
#include "public51.h"
#include "file51.h"
#define RXPIN (*(volatile unsigned char *)PEDATA & 0x10)
#define TXPIN_HIGH (*(volatile unsigned char *)PEDATA |= 0x20)
#define TXPIN_LOW (*(volatile unsigned char *)PEDATA &= ~0x20)
#define TIMER_COUNTER_OVERFLOW (*(volatile unsigned short *)TSTAT & 0x0001)
#define CLEAR_TIMER_OVERFLOW_FLAG (*(volatile unsigned short *)TSTAT &=~0x0001)
#define ENABLE_TIMER (*(volatile unsigned short *)TCTL |= 0x0001)
#define DISABLE_TIMER (*(volatile unsigned short *)TCTL &=~0x0001)
#define ENABLE_TIMER_INT \
(*(volatile unsigned short *)TCTL |= 0x0010); \
(*(volatile unsigned long *)IMR &= ~0x0002)
#define DISABLE_TIMER_INT \
(*(volatile unsigned short *)TCTL &=~0x0010); \
(*(volatile unsigned long *)IMR |= 0x0002)
#define UART_LOCKED_TIMEOUT 3000
#if _DEBUG_
#define DEBUG_BUF_SIZE 25000
char com_buf[DEBUG_BUF_SIZE];
char *com_ptr;
#endif
unsigned short int sgLockFlag;
//检查序列号
unsigned short CheckSerialNumber()
{
#if _DEBUG_
return 1;
#else
unsigned char sn_char1[] = {
SN_CHAR1 - ENCRYPT_CODE,
SN_CHAR2 - (ENCRYPT_CODE+1),
SN_CHAR3 - (ENCRYPT_CODE+2),
SN_CHAR4 - (ENCRYPT_CODE+3),
SN_CHAR5 - (ENCRYPT_CODE+4),
SN_CHAR6 - (ENCRYPT_CODE+5),
SN_CHAR7 - (ENCRYPT_CODE+6),
SN_CHAR8 - (ENCRYPT_CODE+7),
};
unsigned char sn_char2[] = {
SN_CHAR1 + SN_CHAR8 + 2,
SN_CHAR2 + SN_CHAR7 + 4,
SN_CHAR3 + SN_CHAR6 + 6,
SN_CHAR4 + SN_CHAR5 + 8,
};
unsigned char * sn_ptr;
unsigned long addr,offset;
short i;
unsigned char tmp;
#if __TURBOC__
unsigned char serial[8] = {SN_CHAR1,SN_CHAR2,SN_CHAR3,SN_CHAR4,
SN_CHAR5,SN_CHAR6,SN_CHAR7,SN_CHAR8};
addr = serial; offset = 0;
#else
addr = (0X1F0000+10); offset = (0xE000-10);
#endif
sn_ptr = (unsigned char *) addr;
sn_ptr += offset;
for(i=0;i<8;i++)
{
tmp = (unsigned char)(sn_char1[i]+(ENCRYPT_CODE+i));
if( *(sn_ptr+i) != tmp)
return 0;
}
for(i=0;i<4;i++)
{
tmp = (unsigned char)(*(sn_ptr+i) + *(sn_ptr+7-i) + (i<<1) + 2);
if( tmp != sn_char2[i])
return 0;
}
return 1;
#endif
}
/*****************************************************************************************
功 能:设定定时器的定时时间,即多少时间后产生中断。
输入参数:定时时间,以毫秒为单位,最大值65535ms,定时精度为99%,实际定时时间长比目标值略长
注 意:本函数只设定新的定时时间,并不对原计数器的数值清零。
*****************************************************************************************/
void SetTimeoutValueOfTimer(unsigned short int millisecond)
{
*(volatile unsigned short *)TCTL |= 0x0008;
//timer clk source = 32.768K
*(volatile unsigned short *)TPRER = 32;
//prescaler: divider = 33
*(volatile unsigned short *)TCMP = millisecond;
}
/*****************************************************************************************
功 能:复位定时器的计数寄存器,即让计数器从零开始重新计数。
输入参数:无
*****************************************************************************************/
void ResetTimerCounter()
{
DISABLE_TIMER; //stop the timer
ENABLE_TIMER; //start timer and reset the timer counter
}
/*****************************************************************************************
功 能:激活定时器,并允许定时器产生中断
输入参数:无
*****************************************************************************************/
void EnableTimerInt()
{
ENABLE_TIMER_INT;
ENABLE_TIMER;
}
unsigned short int TimerIntOccured()
{
if(*(volatile unsigned long *)ISR & 0x00000002)
return 1;
else
return 0;
}
void ClearTimerIntFlag()
{
*(volatile unsigned short *)TSTAT &= ~0x0001; // clear(by writting 0) the compare flag
*((volatile unsigned char *)ISR+3) &= ~0x02; // clear TIMER interrupt status
}
/****************************************************************************************
功 能:关闭定时器,并禁止定时器产生中断
输入参数:无
*****************************************************************************************/
void DisableTimerInt()
{
DISABLE_TIMER;
DISABLE_TIMER_INT;
}
/*****************************************************************************************
功能:按指定毫秒延时,最大值: 65535ms
*****************************************************************************************/
void DelayMilliSecond(unsigned short ms_value)
{
//最大可设置的延时时间为65535ms,
//延时误差在1%以内,实际延时比目标时间短。
#if __TURBOC__
delay(ms_value);
return;
#else
volatile unsigned short int *clkPtr;
unsigned long count;
unsigned short clkLevel, tmp, clkMask = 0x8000;
count = (ms_value >> 1) * 131 + (ms_value & 0x01) * 66;
// bit 15 of PLLFSR indicates the level of 32.768K crystal,so bit 15 will toggle
// 65.536 times each millisecond.
clkPtr = (volatile unsigned short int *)PLLFSR;
clkLevel = *clkPtr & clkMask;
while(count)
{
while(clkLevel == (tmp = *clkPtr & clkMask) );
clkLevel = tmp;
count--;
}
return;
#endif
}
void EnableUartReceiveInt()
{
*((volatile unsigned char *)IMR+3) &= ~0x04; // clear UART MASK bit
*((volatile unsigned char *)USTCNT+1) |= 0x08; // enable RX READY interrupt
}
void DisableUartReceiveInt()
{
*((volatile unsigned char *)USTCNT+1) &= ~0x08; // disable RX READY interrupt
}
unsigned short int UartReceiveIntOccured()
{
if( (*(volatile unsigned long *)ISR & 0x00000004) && (*(volatile unsigned char *)URX & 0x20) )
return 1;
else
return 0;
}
unsigned char GetUartRxByte()
{
unsigned char byte;
byte = *((volatile unsigned char*)(URX)+1);
#if _DEBUG_
if(com_ptr+4<com_buf+DEBUG_BUF_SIZE && com_ptr>=com_buf)
{
sprintf(com_ptr,"r%02x ",byte);
com_ptr+=4;
}
#endif
return byte;
}
unsigned char PutTxByteToUart(unsigned char tx_byte)
{
while( !(*(volatile unsigned short int *)UTX & 0x8000) );
//wait until the FIFO is empty
*((volatile unsigned char*)UTX +1) = tx_byte;
#if _DEBUG_
if(com_ptr+4<com_buf+DEBUG_BUF_SIZE && com_ptr>=com_buf)
{
sprintf(com_ptr,"t%02x ",tx_byte);
com_ptr+=4;
}
#endif
while( *(volatile unsigned short int *)UTX & 0x0400); //wait until all bit is out
*(volatile unsigned short int *)STPWCH = 3; //to prevent system from sleeping
DelayMilliSecond(1);
if( *(volatile unsigned char *)URX & 0x20)
{
tx_byte = *( (volatile unsigned char *)URX+1); //discard the byte which is sent itself
return 1;
}
DelayMilliSecond(1);
if( *(volatile unsigned char *)URX & 0x20)
{
tx_byte = *( (volatile unsigned char *)URX+1); //discard the byte which is sent itself
return 1;
}
DelayMilliSecond(1);
if( *(volatile unsigned char *)URX & 0x20)
{
tx_byte = *( (volatile unsigned char *)URX+1); //discard the byte which is sent itself
return 1;
}
return 1;
}
void ClearUartIntFlag()
{
*((volatile unsigned char *)ISR+3) &= ~0x04; // clear UART interrupt status
}
void LockUart(void)
{
sgLockFlag = 1;
}
void UnlockUart(void)
{
sgLockFlag = 0;
}
unsigned short int IsUartLocked(void)
{
return sgLockFlag;
}
/******************************************************************************************
名 称:unsigned char ReceiveInTime(unsigned char *bytePtr, unsigned short int time_limit)
功 能:在规定的是时间内等待接收一个字节,如收到,存入bytePtr中后立即返回1,否则超时返回0。
参 数:bytePtr: 存放接收字节的指针
time_limit: 超时时限
返回值:成功接收返回1,否则返回0
*******************************************************************************************/
unsigned char ReceiveInTime(unsigned char *bytePtr, unsigned short int time_limit)
{// receive one byte within time_limit, unit of time_limit: millisecond
// return 1 if received one byte normally, otherwise return 0;
volatile unsigned char *ptr1,*ptr2;
unsigned short timeout;
#if __TURBOC__
unsigned char test[]={0x01,0x05,0x11,
0x6C,0x0,0xF1,0x0,0x60,0x0,0x60,0x0,0x59,0x0,0xf0,0xff,
0x6C,0x0,0x60,0x0,0xF1,0x0,0x3C,0x0,0x08,0x0,0x0B,0x0,0xf0,0xff,
0x6C,0x0,0xF1,0x0,0x60,0x0,0x7C,0x0,0x08,0x0,0x00,0x0,0x8f,0x0,0x1f,0x0,0x1e,0x0,0x2a,0x0,0xf0,0xff,
0x6C,0x0,0xF1,0x0,0x60,0x0,0x7C,0x0,0x15,0x0,0x35,0x0,0x32,0x0,0x57,0x0,0x34,0x0,0x59,0x0,0x53,0x0,0x0b,0x0,0xf0,0xff,
0x6C,0x0,0xF1,0x0,0x60,0x0,0x3C,0x0,0x84,0x0,0xB2,0x0,0xf0,0xff
};
static int i=0;
*bytePtr = test[i++];
if(i>=sizeof(test))
{
i = 0;
return 0;
}
else
return 1;
#endif
if(!IsUartLocked()) //如果未进入空闲帧交换状态,则计数器清零
ResetTimerCounter();
timeout = UART_LOCKED_TIMEOUT;
while(IsUartLocked())
{
DelayMilliSecond(1);
timeout--;
if(!timeout) return 0;
}
ptr1 = (volatile unsigned char *)URX;
ptr2 = ptr1 + 1;
do
{
ResetTimerCounter();
if( *ptr1 & 0x20)
{
*bytePtr = *ptr2;
#if _DEBUG_
if(com_ptr+4<com_buf+DEBUG_BUF_SIZE && com_ptr>=com_buf)
{
sprintf(com_ptr,"R%02X ",*bytePtr);
com_ptr+=4;
}
#endif
return 1;
}
DelayMilliSecond(1);
if(time_limit) time_limit--;
}
while(time_limit);
return 0;
}
/******************************************************************************************
名 称:unsigned short SendOneFullByte(unsigned char uartbyte)
功 能:将指定的字节放入UART的发送寄存器,并等待该字节完全从TXD脚上发送完毕,然后检查接收寄
存器是否收到自身发出的字节,如收到则丢弃,没收到则超过3毫秒亦返回。
参 数:待发送的字节
返回值:成功返回1,否则返回0
*******************************************************************************************/
unsigned short SendOneFullByte(unsigned char uartbyte)
{ //Send a byte and wait until the transmitting completes,
//如在2ms内收到字节,则认为是自己发出的字节,收到后丢弃。
volatile unsigned char tmp;
unsigned short timeout;
#if __TURBOC__
return;
#endif
if(!IsUartLocked()) //如果未进入空闲帧交换状态,则计数器清零
ResetTimerCounter();
timeout = UART_LOCKED_TIMEOUT;
while(IsUartLocked())
{
DelayMilliSecond(1);
timeout--;
if(!timeout) return 0;
}
*(volatile unsigned char *)PESEL &= ~0x20; //PE5(TXD) as TXD
while( !(*(volatile unsigned short int *)UTX & 0x8000) );
//wait until the FIFO is empty
*((volatile unsigned char*)UTX +1) = uartbyte;
DelayMilliSecond(1);
while( *(volatile unsigned short int *)UTX & 0x0400);
//wait untill Uart transmitter is not busy
*(volatile unsigned short int *)STPWCH = 3; //to prevent system from sleeping
#if _DEBUG_
if(com_ptr+4<com_buf+DEBUG_BUF_SIZE && com_ptr>=com_buf)
{
sprintf(com_ptr,"T%02X ",uartbyte);
com_ptr+=4;
}
#endif
DelayMilliSecond(1);
ResetTimerCounter();
timeout = 3;
while(timeout)
{
if( *(volatile unsigned char *)URX & 0x20)
{
tmp = *( (volatile unsigned char *)URX+1); //discard the byte which is sent itself
/*#if _DEBUG_
if(com_ptr+4<com_buf+DEBUG_BUF_SIZE && com_ptr>=com_buf)
{
sprintf(com_ptr,"D%02X ",tmp);
com_ptr+=4;
}
#endif*/
return 1;
}
DelayMilliSecond(1);
timeout--;
}
return 1;
}
void SendOneByteWithoutReceive(unsigned char uartbyte)
{ //Send a byte and wait until the transmitting completes,
//如在2ms内收到字节,则认为是自己发出的字节,收到后丢弃。
*(volatile unsigned char *)PESEL &= ~0x20; //PE5(TXD) as TXD
while( !(*(volatile unsigned short int *)UTX & 0x8000) );
//wait until the FIFO is empty
*((volatile unsigned char*)UTX +1) = uartbyte;
DelayMilliSecond(1);
while( *(volatile unsigned short int *)UTX & 0x0400);
//wait untill Uart transmitter is not busy
return;
}
/*****************************************************************************************
名 称:unsigned char SetUartBaudRate(float divider)
功 能:按指定的分频因子设定UART的波特率
参 数:指定的分频因子
返回值:设置成功返回1,否则返回0
******************************************************************************************/
unsigned char SetUartBaudRate(float divider)
{//return value: 0 == fail, 1 == success
#if __TURBOC__
return 1;
#endif
*(volatile unsigned short *)UBAUD &= ~0x0800; //set baud clk source: system clk
if(divider <= 255.5f)
{ // use non integral prescaler
unsigned char stepvalue;
*(volatile unsigned short *)UBAUD &= ~0x0700;//yth 2004.07.05
*(volatile unsigned short *)NIPR |= 0x8000;
if(divider >= 128.0f)
{ //step: 1/2; tap selection(bit 10,9,8): 110
*(volatile unsigned short *)NIPR |= 0x0600;
*(volatile unsigned short *)NIPR &= ~0x0100;
divider -= 128.0f;
divider *= 2.0f;
divider += 0.5f;
stepvalue = (unsigned char)divider;
*(volatile unsigned char *)((unsigned char *)NIPR + 1) = stepvalue;
return 1;
}
else if(divider >= 64.0f)
{ //step: 1/4; tap selection(bit 10,9,8): 101
*(volatile unsigned short *)NIPR |= 0x0500;
*(volatile unsigned short *)NIPR &= ~0x0200;
divider -= 64.0f;
divider *= 4.0f;
divider += 0.5f;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -