📄 interrupt_usart.c
字号:
//*----------------------------------------------------------------------------
//* ATMEL Microcontroller Software Support - ROUSSET -
//*----------------------------------------------------------------------------
//* The software is delivered "AS IS" without warranty or condition of any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*----------------------------------------------------------------------------
//* File Name : interrupt_Usart.c
//* Object : USART Interrupt Management
//*
//* 1.0 03/Jan/03 JPP : Creation
//* 1.1 25/Jun/03 JPP : adding Wait for USART CLOCK ready
//*----------------------------------------------------------------------------
// Include Standard LIB files
#include "dtm_v3.h"
#include "dtm.h"
#include "externdef.h"
#include "lib_AT91R40008.h"
extern void usart_asm_irq_handler(void);
#define USART_INTERRUPT_LEVEL 6
#define AT91C_US_USMODE_NORMAL AT91C_US_CHMODE_NORMAL
static const unsigned char atmel_header[]={
"\n\r *** Wellcom DTM-66V ***\n\r"
"Copyright (C) 2003-2004 Wellcom Corporations Version: 3.0\n\r"
};
/*#define AT91C_US_ASYNC_MODE ( AT91C_US_CHMODE_NORMAL + \
AT91C_US_NBSTOP_1_BIT + \
AT91C_US_PAR_NONE + \
AT91C_US_CHRL_8_BITS + \
AT91C_US_CLKS_CLOCK )
int AT91F_US_GetChar (const AT91PS_USART pUSART);
void AT91F_US_PutChar (AT91PS_USART pUSART,int character);
_DWORD AT91F_US_SendFrame(AT91PS_USART pUSART,unsigned char *pBuffer,_DWORD szBuffer);
void AT91F_PIO_CfgPeriph(_DWORD periphEnable,_DWORD unused);
void AT91F_PS_EnablePeriphClock(_DWORD periphIds);
void AT91F_US_Configure(AT91PS_USART pUSART,_DWORD mainClock,_DWORD mode,_DWORD baudRate,_DWORD timeguard);
_DWORD AT91F_PDC_SendFrame(AT91PS_PDC pPDC, unsigned char *pBuffer,_DWORD szBuffer);
void AT91F_US_EnableIt (AT91PS_USART pUSART,_DWORD flag);
int AT91F_PDC_IsTxEmpty (AT91PS_PDC pPDC);
int AT91F_PDC_IsRxEmpty(AT91PS_PDC pPDC);
_DWORD AT91F_PDC_SendFrame(AT91PS_PDC pPDC, unsigned char *pBuffer,_DWORD szBuffer );
unsigned int AT91F_US_Baudrate (unsigned int main_clock,unsigned int baud_rate);
void AT91F_US_SetBaudrate (AT91PS_USART pUSART,unsigned int mainClock,unsigned int speed);
void AT91F_US_SetTimeguard(AT91PS_USART pUSART,unsigned int timeguard);
_DWORD AT91F_AIC_ConfigureIt(AT91PS_AIC pAic,_DWORD irq_id,_DWORD priority,_DWORD src_type, unsigned int newHandler); // void (*newHandler) (void));
void AT91F_AIC_EnableIt(AT91PS_AIC pAic,unsigned int irq_id);
*/
_BYTE RecieveByteCom(_WORD OverTime);
_BYTE SendStringCom(_BYTE * str, _BYTE cRetCode, _BYTE cSendMode );
_WORD SendStringComToBuf(_BYTE * str, _BYTE cRetCode, _BYTE cSendMode,_BYTE *cpTragetBuf);
void SendByteCom(_BYTE cChar);
//*------------------------- Interrupt Function -------------------------------
//*----------------------------------------------------------------------------
//* Function Name : Usart_c_irq_handler
//* Object : C handler interrupt function called by the interrupts
//* assembling routine
//* Input Parameters : <RTC_pt> time rtc descriptor
//* Output Parameters : increment count_timer0_interrupt
//*----------------------------------------------------------------------------
void Usart_c_irq_handler(AT91PS_USART USART_pt)
{
_DWORD wStatus;
_BYTE cChar;
_BYTE cRecieveFlag;
_DWORD i;
_DWORD wCmdLength;
_BYTE cCheckSum;
_DWORD wRecCount;
//USART_pt =AT91C_BASE_US1;
//* get Usart status register
wStatus = USART_pt->US_CSR;
if ( wStatus & AT91C_US_RXRDY){
cChar=RecieveByteCom(1000);
if (gcRetCode!=0) return;
switch (cChar) {
case 0x1a:
cRecieveFlag=0; // WLFID命令
wRecCount = 0;
gcpRecBuf[wRecCount++]=cChar;
for (i=1;i<=2;i++) { // 接收命令头 72H,73H
cChar=RecieveByteCom(100);
if (gcRetCode==C_OK) {
gcpRecBuf[wRecCount++]=cChar;
if (cChar!=gcpCmdHead[i]) { // 是命令头
cRecieveFlag=1;
break;
}
}
else {
cRecieveFlag=2;
break;
}
} // end of recieve command head
if (cRecieveFlag==0) { // 开始接收命令长度
cRecieveFlag=0;
for (i=0;i<=1;i++) {
cChar=RecieveByteCom(100);
if (gcRetCode==C_OK) {
gcpRecBuf[wRecCount++]=cChar;
}
else {
cRecieveFlag = 2;
break;
}
}
} // end of recieve command length
else
return;
if ( cRecieveFlag==0) { // 开始接收命令体
cRecieveFlag=0;
wCmdLength=gcpRecBuf[3]* 256 + gcpRecBuf[4];
for(i=0;i<wCmdLength;i++) {
cChar=RecieveByteCom(100);
if (gcRetCode==C_OK) {
gcpRecBuf[wRecCount++]=cChar;
}
else {
cRecieveFlag = 2;
break;
}
}
} // end of recieve command body
else
return;
wRecCount--;
cCheckSum = 0; // 计算检查和
for (i=0;i<wRecCount;i++)
cCheckSum += gcpRecBuf[i];
if ((cRecieveFlag==0)&&(gcpRecBuf[wRecCount]==cCheckSum)) {
CommandProcess(gcpRecBuf); // 进行命令处理
}
return; // end of process 1A type command
default:
return;
} // end of switch cmd type
}
if ( wStatus & AT91C_US_OVRE) {
//* clear US_RXRDY
AT91F_US_GetChar(USART_pt);
AT91F_US_PutChar (USART_pt, 'O');
}
//* Check error
if ( wStatus & AT91C_US_PARE) {
AT91F_US_PutChar (USART_pt, 'P');
}
if ( wStatus & AT91C_US_FRAME) {
AT91F_US_PutChar (USART_pt, 'F');
}
if ( wStatus & AT91C_US_TIMEOUT){
USART_pt->US_CR = AT91C_US_STTTO;
AT91F_US_PutChar (USART_pt, 'T');
}
//* Reset the satus bit
USART_pt->US_CR = AT91C_US_RSTSTA;
}
//*-------------------------- External Function -------------------------------
//*----------------------------------------------------------------------------
//* Function Name : Usart_init
//* Object : USART initialization
//* Input Parameters : none
//* Output Parameters : TRUE
//*----------------------------------------------------------------------------
void Usart_init ( void )
{
COM1= AT91C_BASE_US1;
//* Define RXD and TXD as peripheral
AT91F_PIO_CfgPeriph(AT91C_BASE_PIO,AT91C_P22_RXD1 | AT91C_P21_TXD1,0);
// First, enable the clock of the PIOB
AT91F_PS_EnablePeriphClock ( AT91C_BASE_PS, 1<<AT91C_ID_US1 ) ;
// Usart Configure
AT91F_US_Configure (COM1, MCK,AT91C_US_ASYNC_MODE, BAUDRATE, 0);
// Enable usart
COM1->US_CR = AT91C_US_RXEN | AT91C_US_TXEN;
//* Enable USART IT error and RXRDY
AT91F_US_EnableIt(COM1,AT91C_US_TIMEOUT | AT91C_US_FRAME | AT91C_US_OVRE |AT91C_US_RXRDY);
//* open Usart 1 interrupt
AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_US1, USART_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, (unsigned int)usart_asm_irq_handler);
AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_US1);
//AT91F_US_PutChar (COM1,'X');
AT91F_US_SendFrame(COM1,(unsigned char *)atmel_header,sizeof(atmel_header));
}
//*----------------------------------------------------------------------------
//* 从串口接收一个字符,带超时处理
//* 如果超时,gRetCode =1 若接收到字符,函数返回gRetCode=0
//* 函数的返回值为接收到的字符,若超速,函数的返回值为0
//* 函数的参数为超时时间(毫秒)
//*----------------------------------------------------------------------------
_BYTE RecieveByteCom(_WORD OverTime)
{
_WORD i,wStatus;
_BYTE ch;
while(OverTime--) {
for (i=0;i<500;i++) {
wStatus = COM1->US_CSR;
if ( wStatus & AT91C_US_RXRDY) {
ch=AT91F_US_GetChar(COM1);
COM1->US_CR = AT91C_US_RSTSTA;
gcRetCode=C_OK;
return(ch);
}
}
}
gcRetCode=C_TIMEOUT;
return (0);
}
//*----------------------------------------------------------------------------
//向串口发送一个字符串,
// str字符串,第一个字节位长度
// bRetCode,发送的命令中的返回码
// bSendMode,发送方式
// =0x00, 表示发送返回码和检查和
// =0x01, 表示不发送返回码和检查和,只发送命令本身
//*----------------------------------------------------------------------------
_BYTE SendStringCom(_BYTE * str, _BYTE cRetCode, _BYTE cSendMode )
{
_BYTE k=0;
_BYTE cStrLen;
_BYTE cCheckSum=0;
cStrLen =*str; // 取长度
k=1;
do
{
SendByteCom(*(str + k));
cCheckSum += *(str + k);
k++;
} while(k <= cStrLen);
if (cSendMode==0x00) {
SendByteCom(cRetCode); // 发返回码低位
cCheckSum += cRetCode ;
SendByteCom(cCheckSum); // 发送检查和
}
return (cCheckSum);
}
//*----------------------------------------------------------------------------
//向串口发送一个字符串,
// str字符串,第一个字节位长度
// bRetCode,发送的命令中的返回码
// bSendMode,发送方式
// =0x00, 表示发送返回码和检查和
// =0x01, 表示不发送返回码和检查和,只发送命令本身
// wSize: 返回字节数
//*----------------------------------------------------------------------------
_WORD SendStringComToBuf(_BYTE * str, _BYTE cRetCode, _BYTE cSendMode,_BYTE *cpTragetBuf)
{
_WORD k=0,wSize=0;
_WORD cStrLen;
_BYTE cCheckSum=0;
cStrLen =*str; // 取长度
k=1;
do
{
cpTragetBuf[wSize++] = *(str + k);
cCheckSum += *(str + k);
k++;
} while(k <= cStrLen);
if (cSendMode==0x00) {
cpTragetBuf[wSize++] = cRetCode; // 发返回码低位
cCheckSum += cRetCode ;
cpTragetBuf[wSize++] = cCheckSum; // 发送检查和
}
return (wSize);
}
//*----------------------------------------------------------------------------
// 向串口发送一个字符
//*----------------------------------------------------------------------------
void SendByteCom(_BYTE cChar)
{
while ( !( COM1->US_CSR & AT91C_US_TXRDY ));
AT91F_US_PutChar (COM1,cChar);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -