📄 usart.c
字号:
//usart.c for lc ODU
#include <stdio.h>
#include "usart.h"
#include "AT91SAM7S128.h"
#include "crc.h"
#include "vars.h"
#include "cmdrun.h"
#include <stdlib.h>
#define AT91C_MASTER_CLOCK 48000000
extern void Delay (unsigned long a);
unsigned char rx_buf[256]; //接收缓冲区
unsigned char tx_buf[256]; //发送缓冲区
unsigned int hd_flag=0;//接收数据阶段标志
unsigned int rx_index,rx_len,tx_index,tx_len; //接收、发送数组下标及长度
extern unsigned long Alive_counter;//发送Alive消息计时器
AT91PS_PIO u_pPio = AT91C_BASE_PIOA;
AT91PS_PMC u_pPMC = AT91C_BASE_PMC;
AT91PS_USART u_pUSART0 = AT91C_BASE_US0;
AT91PS_USART u_pUSART1 = AT91C_BASE_US1;
AT91PS_MC u_pMC = AT91C_BASE_MC;
AT91PS_AIC u_pAic = AT91C_BASE_AIC;
void InitUSART0() { // 初始化 UART0
u_pPio->PIO_PDR = BIT5 | BIT6 | BIT21 | BIT22;
u_pPio->PIO_ASR = BIT5 | BIT6 | BIT21 | BIT22;
u_pPio->PIO_BSR = 0;
u_pPMC->PMC_PCER = 1<<AT91C_ID_US0; // 允许 UART0 时钟
u_pUSART0->US_BRGR = 240; // 设置波特率因子 ((18.432MHz*4)/(19200x16))
u_pUSART0->US_TTGR = 0;
u_pUSART0->US_MR = 0x08c0; // 设置UART0工作方式:9600波特率。8数据,1位停止位,无校验
u_pUSART0->US_PTCR = AT91C_PDC_TXTEN | AT91C_PDC_RXTEN; // 允许RX和TX进行PDC传送请求
u_pUSART0->US_RPR = (unsigned int)recv_dma;//PDC_RPR 的值为recv_dma的地址
u_pUSART0->US_RNPR =(unsigned int)recv_dma;;
u_pUSART0->US_TPR = (unsigned int)send_dma;//PDC_TPR 的值为send_dma的地址
//u_pUSART0->US_TNPR = US0T_DMA_ADDR;
u_pUSART0->US_RCR = MAX_RECV_BUF;
u_pUSART0->US_RNCR = MAX_RECV_BUF;
u_pUSART0->US_TCR = 0;
u_pUSART0->US_CR = 0x50; // 允许UART0
//recv_point=MAX_RECV_BUF;
send_point=0;
tx_wr_pt=0;
rx_rd_pt=0;
/*因为全局变量在定义时已经分配了一个固定的内存地址,所以无法再更改其地址*/
//send_dma=(unsigned char *)tbuf_addr;//US0T_DMA_ADDR;//(u_pUSART0->US_TPR);
//recv_dma=(unsigned char *)rbuf_addr;//US0R_DMA_ADDR;//(u_pUSART0->US_RPR);
}
/*
unsigned int write_char_USART0(unsigned char ch) { // 向UART0写入字符数据
if (!(u_pUSART0->US_CSR&AT91C_US_TXRDY)==1) return 0;
u_pUSART0->US_THR = ((ch & 0x1FF));
return 1;
}
unsigned char read_char_USART0(void) { // 从UART0读取字符数据
if((u_pUSART0->US_CSR&AT91C_US_RXRDY)==1)
{recv_dma[MAX_RECV_BUF-recv_point]=((u_pUSART0->US_RHR) & 0x0FF);
if(recv_point>0) recv_point--;
else recv_point=MAX_RECV_BUF;
}
return 0;
}
unsigned char read_char_USART0_nonstop(void) { // 从UART0读取字符数据,无停止位
if((u_pUSART0->US_CSR&AT91C_US_RXRDY)==1)
return((u_pUSART0->US_RHR) & 0x1FF);
else return 0;
}
void write_str_USART0(unsigned char* buff) { // 向UART0写入字符串数据 for debug
unsigned int i = 0x0;
while(buff[i] != '\0') {
write_char_USART0(buff[i]);
i++;
}
}
*/
unsigned char send_triger; //for debug^^^^^^^^^^^^^^^^^for debug
void send_msg_USART0(){
if(tx_wr_pt!=send_point) {
Alive_counter=0;
if(send_point<tx_wr_pt){
u_pUSART0->US_TPR=send_point+(unsigned int)send_dma;
u_pUSART0->US_TCR=tx_wr_pt-send_point;
send_point=tx_wr_pt;
send_triger=1;
}
else
{
u_pUSART0->US_TPR=send_point+(unsigned int)send_dma;
u_pUSART0->US_TCR=MAX_SEND_BUF-send_point;
send_point=0;
send_triger=1;
}
}
}
/*
void ClearTerminal(void) {
write_char_USART0(0x0d); // 回车
write_char_USART0(0x0a); // 换行
}
*/
/*将ACK帧写入PDA内存*/
void send_ack()
{ unsigned char datalink_buf[5];
datalink_buf[0]=0x7e;
datalink_buf[1]=0xff;
datalink_buf[2]=0x00;
datalink_buf[3]=0xff;
datalink_buf[4]=0x7e;
//write_frame_USART0(datalink_buf,5);
for(int j=0;j<5;j++)
{
send_dma[tx_wr_pt++]=datalink_buf[j];
if(tx_wr_pt>=MAX_SEND_BUF) tx_wr_pt=0;
//for debug^^^^^^^^^^
printf("%x ",datalink_buf[j]);
//if(write_char_USART0(datalink_buf[j])==0) j--; /*for debuging^^^^^^^^^^^^^^^^^^^for debug*/
}
}
/*将需要传输的信息打包,组成一个应用层信息帧*/
void msg_pack(unsigned char type,unsigned char id,unsigned char ack,unsigned char exinfor) //application layer
{
unsigned int i,j,plen;
unsigned char tmp_buf[32];
//memset(tmp_buf,0,1);
tmp_buf[0]=type;
tmp_buf[1]=id;
tmp_buf[2]=ack;
plen=3;
//for(i=0;i<plen;i++)
//tmp_buf[i+2]=payload[i];
if(ack!=0)
{ load_msg(tmp_buf,3); //数据链路层打包,并写入待发送存储区,非正确应答
return;
}
/*如果ack=0执行以下代码*/
if(type==0x00){/*spontaneous message*/
plen=2;
switch(id){
case 0x01://alarm
tmp_buf[plen++]=v_odu_alarm[0] | v_alarm_sim[0];
tmp_buf[plen++]=v_odu_alarm[1] | v_alarm_sim[1];
break;
case 0x02://configuration
for(i=0;i<MAX_CONF_NUM;i++)
{
if(exinfor==v_cfg_data[i].no)
break;
}
if(i<MAX_CONF_NUM)
{ ack=0;
for(j=0;j<v_cfg_data[i].len;j++)
tmp_buf[plen++]=v_cfg_data[i].value[j];
}
else return;
break;
case 0x05://measurement
tmp_buf[plen++]=v_tx_power&0x0ff;
tmp_buf[plen++]=(v_tx_power>>8)&0x0ff;
if(exinfor==0x01){
plen=5;
}
else if(exinfor==0xff){
tmp_buf[plen++]=v_rx_power&0x0ff;
tmp_buf[plen++]=(v_rx_power>>8)&0x0ff;
tmp_buf[plen++]=v_temp_value&0x0ff;
tmp_buf[plen++]=(v_temp_value>>8)&0x0ff;
}
else
{
return;
}
break;
case 0x07://reset
tmp_buf[plen++]=v_reset;
break;
case 0x08://software version
for(i=0;i<2;i++)
{
tmp_buf[plen++]=v_soft_ver[i].active_image;
tmp_buf[plen++]=v_soft_ver[i].version/100+0x30;
tmp_buf[plen++]=(v_soft_ver[i].version%100)/10+0x30;
tmp_buf[plen++]=v_soft_ver[i].version%10+0x30;
tmp_buf[plen++]=v_soft_ver[i].flag;
tmp_buf[plen++]=v_soft_ver[i].day/10+0x30;
tmp_buf[plen++]=v_soft_ver[i].day%10+0x30;
tmp_buf[plen++]=v_soft_ver[i].month/10+0x30;
tmp_buf[plen++]=v_soft_ver[i].month%10+0x30;
tmp_buf[plen++]=(v_soft_ver[i].year%100)/10+0x30;
tmp_buf[plen++]=v_soft_ver[i].year%10+0x30;
}
break;
/*case 0x09://flash access--------adding on 07-0924
break;*/
case 0x20://alive message
tmp_buf[plen++]=v_counter;
break;
case 0x21://RxPower
tmp_buf[plen++]=v_rx_power;
break;
case 0x22://TxPower
tmp_buf[plen++]=v_tx_power;
break;
/*case 0x24://RpsControl
break;*/
case 0x25://RpsAlarm
tmp_buf[plen++]=v_rpsalarm;
break;
/*case 0x26://ODU control
break;*/
default:
break;
}
}
else if(type==0x01){//response message
switch(id){
case 0x01://alarm
tmp_buf[plen++]=v_odu_alarm[0] | v_alarm_sim[0];
tmp_buf[plen++]=v_odu_alarm[1] | v_alarm_sim[1];
break;
case 0x02://configuration
for(i=0;i<MAX_CONF_NUM;i++)
{
if(exinfor==v_cfg_data[i].no)
break;
}
if(i<MAX_CONF_NUM)
{ ack=0;
for(j=0;j<(v_cfg_data[i].len);j++)
tmp_buf[plen++]=v_cfg_data[i].value[j];
}
else ack=0x87;//--------------------未定义变量???????????
tmp_buf[2]=ack;
break;
case 0x03://filetransfer/*已经在ftrans_pro 函数中处理了*/
tmp_buf[2]=ack;
break;
case 0x05://measurement
tmp_buf[plen++]=v_tx_power&0x0ff;
tmp_buf[plen++]=(v_tx_power>>8)&0x0ff;
if(exinfor==0x01){
plen=5;
}
else if(exinfor==0xff){
tmp_buf[plen++]=v_rx_power&0x0ff;
tmp_buf[plen++]=(v_rx_power>>8)&0x0ff;
tmp_buf[plen++]=v_temp_value&0x0ff;
tmp_buf[plen++]=(v_temp_value>>8)&0x0ff;
}
else
{
ack=ACK_VALINVALID;
tmp_buf[2]=ack;
plen=3;
}
break;
case 0x07://reset
tmp_buf[plen++]=v_reset;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -