首页 技术 正文
技术 2022年11月10日
0 收藏 539 点赞 4,047 浏览 11668 个字
#include <avr/io.h>#include <avr/interrupt.h>#include <util/delay.h>//#include <avr/wdt.h>#define SYNC 0x40#define PARITY_EVEN 0x20#define PARITY_ODD 0x30#define STOP_2 0x04#define DATA_5 0x00#define DATA_6 0x02#define DATA_7 0x04#define DATA_8 0x06 //最高位置1,UMSELn设为0工作于异步模式#define DATA_9 0x0c#define FRAMING_ERROR (1<<FE)#define PARITY_ERROR (1<<UPE)#define DATA_OVERRUN (1<<DOR)#define DATA_REGISTER_EMPTY (1<<UDRE)#define RX_COMPLETE (1<<RXC)#define SYSTEM_CLOCK 16000000L#define BAUD_RATE 38400L//57600L测试通过#define UART_RX_BUFFER_SIZE 1024#define UART_RX_BUFFER_MASK (UART_RX_BUFFER_SIZE-1)#if (UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK)#error RX buffer size is not a power of 2#endif#define UART_TX_BUFFER_SIZE 512#define UART_TX_BUFFER_MASK (UART_TX_BUFFER_SIZE-1)//UART_RX_BUFFER_SIZE 128#if (UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK)#error TX buffer size is not a power of 2#endifvolatile static unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE];//UART_RX_BUFFER_SIZE 128volatile static unsigned char UART_RxHead;volatile static unsigned char UART_RxTail;volatile static unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE];//UART_TX_BUFFER_SIZE 128volatile static unsigned char UART_TxHead;volatile static unsigned char UART_TxTail;//volatile staticunsigned char UART0_RxBuf[UART_RX_BUFFER_SIZE];//UART_RX_BUFFER_SIZE 128volatile static unsigned char UART0_RxHead;volatile static unsigned char UART0_RxTail;volatile static unsigned int UART0_TxBuf[UART_TX_BUFFER_SIZE];//UART_TX_BUFFER_SIZE 128volatile static unsigned char UART0_TxHead;volatile static unsigned char UART0_TxTail;//volatile staticunsigned char UART1_RxBuf[UART_RX_BUFFER_SIZE];//UART_RX_BUFFER_SIZE 128volatile static unsigned char UART1_RxHead;volatile static unsigned char UART1_RxTail;volatile static unsigned char UART1_TxBuf[UART_TX_BUFFER_SIZE];//UART_TX_BUFFER_SIZE 128volatile static unsigned char UART1_TxHead;volatile static unsigned char UART1_TxTail;void Initialize(void);void Serial_Initialize_UART0(unsigned long int baud);void Serial_Initialize_UART1(unsigned long int baud);void Timer0_Initialize(void);void Timer3_Initialize(void);unsigned char UART0_ReceiveByte(void);void UART0_TransmitByte(unsigned char data);unsigned char UART1_ReceiveByte(void);void UART1_TransmitByte(unsigned char data);void UART0_TransmitC(unsigned char c);void UART0_TransmitString(unsigned char *ptr);void UART1_TransmitC(unsigned char c);void UART1_TransmitString(unsigned char *ptr);void SendDataUp();void SendDataDown(void);extern unsigned char ReadTime(void);unsigned char strCat(unsigned char *s1,unsigned char *s2);void Initialize(void){     //MCUCR=0x00;//PORTA,PORTC作普通口使用 Serial_Initialize_UART0(BAUD_RATE); Serial_Initialize_UART1(BAUD_RATE); //Timer0_Initialize(); Timer3_Initialize(); sei();}void Serial_Initialize_UART0(unsigned long int baud){ unsigned short int ubrr0; ubrr0=((SYSTEM_CLOCK/(16L*baud))-1); UBRR0H=(unsigned char)(ubrr0>>8);//设置USART0波特率 UBRR0L=(unsigned char)ubrr0; //UCSR0B=((1<<TXCIE0)|(1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0));//USART0接收结束中断使能,接收器发送器使能 UCSR0B=((1<<RXEN0)|(1<<TXEN0));//初始化时先先进入定时中断,屏蔽接收发送中断, UCSR0C=DATA_8; //异步,无奇偶校验,1位停止位,8数据位 UART0_RxTail=0; UART0_RxHead=0; UART0_TxTail=0; UART0_TxHead=0;}void Serial_Initialize_UART1(unsigned long int baud){ unsigned short int ubrr1; ubrr1=((SYSTEM_CLOCK/(16L*baud))-1); UBRR1H=(unsigned char)(ubrr1>>8);//设置USART1波特率 UBRR1L=(unsigned char)ubrr1; //UCSR1B=((1<<TXCIE1)|(1<<RXCIE1)|(1<<RXEN1)|(1<<TXEN1));//USART1接收结束中断使能,接收器发送器使能 UCSR1B=((1<<RXEN1)|(1<<TXEN1));//初始化时先不打开接收发送中断 UCSR1C=DATA_8; //异步,无奇偶校验,1位停止位,8数据位 UART1_RxTail=0; UART1_RxHead=0; UART1_TxTail=0; UART1_TxHead=0;}void Timer0_Initialize(void){cli();TCNT0=0x63;//((0xff-0x63)+1)*1024*(1/16M)=10msTCCR0=0x07;//定时器0 预分频比1024TIMSK=0x01;//开定时器0中断}void Timer3_Initialize(void){TCCR3B = 0x00;  //stop timer //0.1s  0xffff+1-(16M/1024)*0.1=63973.5--0xf9e5//0.2s--0xf3cb//0.3s--0xEDB0//TCNT3H=0xff;//TCNT3L=0x64;//TCCR3B=0x05;//1024预分频TCNT3H=0xf3;TCNT3L=0xcb;TCCR3B=0x04;//256预分频ETIMSK|= (1 << TOIE3);//定时器3溢出中断}//由于单片机要实现和DTU与modbus模块的同时通讯,采用双串口CPU,//串口0中断处理与DTU的数据通讯,串口1中断处理与modbus数据采集模块的通讯,//串口0中断设置为高优先级中断,每接收到或发送完一个字节都进入中断处理,处理完毕立即退出中断//通讯波特率都为38400 b/s,一个起始位,一个停止位。//时间冲突问题,硬件接受或发送一个字节的时间为1 ms左右,而软件接受或发送一个字节的时间仅几μs。//同时通讯实际上是将CPU时间分成很小的时间片,假设较快的串口发送或接受一个字节的最长时间为TRbyteMax,则CPU最长时间片一般应小于TRbyteMax/2,当然在接受或发送完一帧数据之后的间隙,CPU时间片可以适当延长,作一些必要的数据处理。 //数据冲突问题,2个串口通讯分别使用各自的接受发送数据缓冲区和控制变量, //以减少中断保护数据量和防止数据冲突。 //当主程序、串口2中断处理程序和其他中断处理程序往存储器中写数据时, //需在尽量短的时间内关闭串口1中断,关闭中断时间应小于几百μs, //防止其他程序数据没有写完之前串口1读此数据。//UART0接收完成中断SIGNAL(SIG_UART0_RECV){     unsigned char data; unsigned char tmphead; data=UDR0;//read the received data //calculate buffer index tmphead=(UART0_RxHead+1)&UART_RX_BUFFER_MASK;//UART_RX_BUFFER_MASK 127 UART0_RxHead=tmphead;//store new index     if(tmphead==UART0_RxTail)  { //ERROR! Receive buffer overflow     } UART0_RxBuf[tmphead]=data; //store received data in buffer //if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)}void UART0_ReceiveData(void){ unsigned char UART0_RxBuf[UART_RX_BUFFER_SIZE] = {0}; UCSR0B |= (1<<RXCIE0);}//UART1接收完成中断SIGNAL(SIG_UART1_RECV){     unsigned char data; unsigned char tmphead; data=UDR1;/* read the received data */ //calculate buffer index tmphead=(UART1_RxHead+1)&UART_RX_BUFFER_MASK;//UART_RX_BUFFER_MASK 127 UART1_RxHead=tmphead;//store new index     if(tmphead==UART1_RxTail)  { /* ERROR! Receive buffer overflow */     } UART1_RxBuf[tmphead]=data; //store received data in buffer}//UART0数据寄存器空中断SIGNAL(SIG_UART0_DATA){     unsigned char tmptail; if(UART0_TxHead!=UART0_TxTail)//check if all data is transmitted {/* calculate buffer index */     tmptail=(UART0_TxTail+1)&UART_TX_BUFFER_MASK;//UART_TX_BUFFER_SIZE 128 UART0_TxTail=tmptail;//store new index UDR0=UART0_TxBuf[tmptail];//start transmition } else {     UCSR0B&=~(1<<UDRIE);//disable UDRE interrupt }}//UART1数据寄存器空中断SIGNAL(SIG_UART1_DATA)//SIGNAL(SIG_UART1_TRANS){     unsigned char tmptail; if(UART1_TxHead!=UART1_TxTail)//check if all data is transmitted {/* calculate buffer index */     tmptail=(UART1_TxTail+1)&UART_TX_BUFFER_MASK;//UART_TX_BUFFER_SIZE 128 UART1_TxTail=tmptail;//store new index UDR1=UART1_TxBuf[tmptail];//start transmition } else {     UCSR1B&=~(1<<UDRIE);//disable UDRE interrupt }}unsigned char timer0count=0;void ReadHoldRegister(void);SIGNAL(SIG_OVERFLOW0){TIMSK=0x00;//关定时器0中断timer0count++;//DDRA  |=(1<<3);//测试能否进入溢出中断//PORTA |=(1<<3);//_delay_ms(3000);//PORTA &=~(1<<3);//_delay_ms(3000);ReadHoldRegister();if(timer0count==15)//150ms{//sendcommand(3,0x03,0x01);//读输入寄存器,startAddr,RegNumTIMSK=0x01;//开定时器0中断}}SIGNAL(SIG_OVERFLOW3){ETIMSK=0x00;//关定时器3溢出中断//DDRA  |=(1<<3);//测试能否进入溢出中断//PORTA ^=(1<<3);ReadHoldRegister();ETIMSK|= (1 << TOIE3);//开定时器3溢出中断}//将两个字符串连接起来unsigned char strCat(unsigned char *s1,unsigned char *s2){int i=0,j=0;while(s1[i]!='\0')i++;while(s2[j]!='\0')s1[i++]=s2[j++];s1[i]='\0';return *s1;}unsigned char UART0_ReceiveByte(void){     unsigned char tmptail; while(UART0_RxHead==UART0_RxTail);//wait for incoming data //caculate buffer index tmptail=(UART0_RxTail+1)&UART_RX_BUFFER_MASK;//UART_RX_BUFFER_MASK 127 UART0_RxTail=tmptail;//store new index return UART0_RxBuf[tmptail];//return data}unsigned char UART1_ReceiveByte(void){     unsigned char tmptail; while(UART1_RxHead==UART1_RxTail);//wait for incoming data //caculate buffer index tmptail=(UART1_RxTail+1)&UART_RX_BUFFER_MASK;//UART_RX_BUFFER_MASK 127 UART1_RxTail=tmptail;//store new index return UART1_RxBuf[tmptail];//return data}//发送采用查询方式//USART0发送字符unsigned char UART0_Receive(void){/* 等待接收数据*/while ( !(UCSR0A & (1<<RXC0)) );/* 从缓冲器中获取并返回数据*/return UDR0;}void UART0_TransmitByte(unsigned char data){     unsigned char tmphead; //caculate buffer index tmphead=(UART0_TxHead+1)&UART_TX_BUFFER_MASK;//UART_TX_BUFFER_SIZE 128 while(tmphead==UART0_TxTail);//wait for free space in buffer UART0_TxBuf[tmphead]=data;//store new data in buffer UART0_TxHead=tmphead;//store new index UCSR0B|=(1<<UDRIE);//enable UDRIE interrupt}void UART1_TransmitByte(unsigned char data){     unsigned char tmphead; //caculate buffer index tmphead=(UART1_TxHead+1)&UART_TX_BUFFER_MASK;//UART_TX_BUFFER_SIZE 128 while(tmphead==UART1_TxTail);//wait for free space in buffer UART1_TxBuf[tmphead]=data;//store new data in buffer UART1_TxHead=tmphead;//store new index UCSR1B|=(1<<UDRIE);//enable UDRIE interrupt}//发送采用查询方式//USART0发送字符void UART0_Transmit_c(unsigned char c){ while(!(UCSR0A & (1<<UDRE)));//wait for empty transmit buffer UDR0=c;}//USART1发送字符void UART1_Transmit_c(unsigned char c) //发送采用查询方式{ while(!(UCSR1A & (1<<UDRE)));//wait for empty transmit buffer UDR1=c;}void UART0_Transmit_String(unsigned char *ptr){ while (*ptr) {  UART0_TransmitByte(*ptr++); } UART0_Transmit_c(0x0D);//结尾发送回车 UART0_Transmit_c(0x0A);//结尾发送换行}//USART1发送字符串void UART1_Transmit_String(unsigned char *ptr){ while (*ptr) {  UART1_TransmitByte(*ptr++); } UART1_Transmit_c(0x0D);//结尾发送回车 UART1_Transmit_c(0x0A);//结尾发送换行}void UART0_Transmit_HEX(unsigned char *ptr, int nLen){ for(int i=0; i<nLen; i++) {  UART0_Transmit_c(ptr[i]); }}void UART1_Transmit_HEX(unsigned char *ptr, int nLen){ for(int i=1; i<nLen; i++) {  UART1_Transmit_c(ptr[i]); }}/*void wdt_init(void){asm("wdr");//clr wdtWDTCR=0x0F;//enable wdt,clk = 2048,1.8S}void watchdog_on(void){//看门狗计数清零asm("WDR"); //WDTCR=0x1F;  //使能watchdog,并且,采用1024K分频,典型溢出时间5V时1S WDTCR = (1 << WDE)|(1 << WDP2) | (1 << WDP1) | (1 << WDP0); // 启动看门狗定时, 复位周期为1S} void WDT_off(void){//WDT复位asm("wdr");//置位WDCE 和 WDEWDTCR = (1<<WDCE) | (1<<WDE);//关闭WDTWDTCR = 0x00;}*/unsigned short crc16(unsigned char* puchMsg, unsigned char usDataLen);//往服务器发送数据void ReadHoldRegister(void){/*unsigned char data_up;unsigned char CompayID[]={"shanghailianxun "};unsigned char DeviceCode[]={"DeviceCode "};unsigned char TransmitTimeStamp[]={"TimeStamp "};unsigned char DDC_Name[]={"DDC_0001 "};unsigned char NV_Name[]={"NV_001 "};unsigned char State[]={"State "};unsigned char Space[]={" "};unsigned char NVF[]={"NVF "};unsigned char CRCCode16[]={"CRCCode"};//TransmitTimeStamp[] = ReadTime();UCSR0B |=(1<<RXCIE0);//开USART0收中断UCSR1B |=(1<<TXCIE1);//开USART1发中断UART1_Transmit_String(CompayID);UART1_Transmit_String(DeviceCode);UART1_Transmit_String(TransmitTimeStamp);UART1_Transmit_String(DDC_Name);UART1_Transmit_String(NV_Name);UART1_Transmit_String(State);UART1_TransmitByte(data_up);//UART1_Transmit_String(UART0_RxBuf);UART1_Transmit_String(Space);UART1_Transmit_String(NVF);UART1_Transmit_String(CRCCode16);UART1_TransmitByte('\r');UART1_TransmitByte('\n');UCSR0B &=~(1<<RXCIE0); UCSR1B &=~(1<<TXCIE1);//关*/     unsigned char TransmitBuff[8] = {0}; TransmitBuff[0] = 0x01;     TransmitBuff[1] = 0x03; TransmitBuff[2] = 0x00;  TransmitBuff[3] = 0x00;  TransmitBuff[4] = 0x00;     TransmitBuff[5] = 0x0f;unsigned short wCrc = 0;wCrc = crc16(TransmitBuff, 6);  TransmitBuff[6] = (wCrc &0xFF00)>>8;  TransmitBuff[7] = (unsigned char)(wCrc &0x00FF);cli();//发送前清除所有中断 UART0_Transmit_HEX(TransmitBuff,8);sei();//发送完成后打开中断//UCSR0B |= (1<<RXCIE0);UART0_ReceiveData();_delay_ms(30);/*_delay_ms(20);_delay_ms(20);_delay_ms(20);_delay_ms(20);_delay_ms(20);_delay_ms(20);_delay_ms(20);_delay_ms(20);*/cli();  UART1_Transmit_HEX(UART0_RxBuf,36);    sei();   //_delay_ms(100); //data_up=UART0_ReceiveByte();/*       unsigned char ReceiveBuff[128] = {0}; for (int n=0; n<35; n++) {     ReceiveBuff[n]=UART0_Receive(); } UART1_Transmit_HEX(ReceiveBuff,35 );*/}//往设备发送数据void SendDataDown(void){//unsigned char data_down;//unsigned char CompayID[]={"shanghailianxun "};unsigned char DeviceCode[]={"DeviceCode "};unsigned char TransmitTimeStamp[]={"TimeStamp "};unsigned char DDC_Name[]={"DDC_0001 "};unsigned char NV_Name[]={"NV_001 "};unsigned char State[]={"State "};unsigned char Space[]={" "};unsigned char NVF[]={"NVF "};unsigned char CRCCode16[]={"CRCCode"};//data_down=UART1_ReceiveByte();//ReadTime();{UART0_Transmit_String(DeviceCode);UART0_Transmit_String(TransmitTimeStamp);UART0_Transmit_String(DDC_Name);UART0_Transmit_String(NV_Name);UART0_Transmit_String(State);//UART0_TransmitByte(data_down);UART0_Transmit_String(UART1_RxBuf);UART0_Transmit_String(Space);UART0_Transmit_String(NVF);UART0_Transmit_String(CRCCode16);UART0_TransmitByte('\r');UART0_TransmitByte('\n');}}int main(void){//unsigned char code str[] = "shanghailianxun";//unsigned char *pstr = str;//while(*pstr)//{  //send_a_char(*pstr);  //pstr ++;//}     Initialize(); //PORTB=0xff; //watchdog_on();    //_delay_ms(100);//UART1_Transmit_String(string1);//UART1_TransmitByte('\n');while(1){//data_down=UART1_ReceiveByte();;//ReadHoldRegister();//SendDataDown();}}

  

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,104
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,581
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,428
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,200
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,835
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,918