M64,14.7456M晶振
定时器中断时间为1s,如果发送间隔大于T1.5但小于T3.5的数据丢弃
SIGNAL(SIG_UART0_RECV)
{
Com0_Receive_Data_Buffer[Com0_Receive_Cout]=UDR0;
if(Com0_Receive_Cout<18) Com0_Receive_Cout++;
Uart_Fin = 5;
Rcvflag = 2;
Uart_Start = 1;
}
SIGNAL (SIG_UART0_TRANS)
{
Com0_Send_Data_Pointer++;
Com0_Send_Data_Bytes--;
if(Com0_Send_Data_Bytes>0)
UDR0=*Com0_Send_Data_Pointer;
else
UCSR0B|=( 1<
}
INTERRUPT(SIG_OVERFLOW0)
{
TCNT0 = 240; //reload counter value
flag1ms = 1;
}
void timeProc(void)
{
wdt_reset();
if(flag1ms == 1)
{
flag1ms = 0;
if(Uart_Start == 1)//串口开始接收数据
{
if(Rcvflag>0) Rcvflag--;//1.5T的变量
if(Uart_Fin>0) Uart_Fin--;3.5T的变量
if(Rcvflag == 0)//δ½áÊø¶ªÆú//1.5T的时间到了,记录长度
{
Com0_Receive_Cout15 = Com0_Receive_Cout;
}
if((Uart_Fin == 0)&&(Uart_Send==0))//½áÊø//3.5T的时间到
{
if(Com0_Receive_Data_Buffer[0]==Com0_Send_Data_Buffer[0])/////
{
if(Com0_Receive_Cout15 == Com0_Receive_Cout)//判断接收的过程中有没有超过T1.5
{
Uart_End = 5;
Uart_Send = 1;
}
else
{
Com0_Receive_Cout = 0;
}
}
else
{
Com0_Receive_Cout = 0;
Uart_Start =0;
}
}
if(Uart_End > 0)//一桢数据结束,延长>T3.5发送
{
Uart_End--;
if(Uart_End == 0)
{
Com0_Receive_CRCcouter=Com0_Receive_Cout;
Com0_Receive_Cout = 0;
Com0_Communication( ) ;//该部分可参考论坛上的相关程序
Uart_Start =0;
Uart_Send = 0;
}
}
}
}
}
void main (void)
{
unsigned char Sumad,kk;
cli();
initTimer();
sei();
while(1)
{
timeProc();
}
}
void initTimer(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 240; //set count
TIMSK |=0X01;
TCCR0 = 0x07; //start timer
}
void Com0_Communication(void)
{
unsigned short crcresult;
unsigned char temp[2];
crcresult= getCRC16(Com0_Receive_Data_Buffer,Com0_Receive_CRCcouter-2);
temp[1]=crcresult & 0xff;
temp[0]=(crcresult >> 8) & 0xff;
if((Com0_Receive_Data_Buffer[Com0_Receive_CRCcouter-1]==temp[0])&&(Com0_Receive_Data_Buffer[Com0_Receive_CRCcouter-2]==temp[1]))
{
PORTB^=0x20;
switch(Com0_Receive_Data_Buffer[1])
{
case 0x01:
Modbus_Function_1();
break;
case 0x03:
Modbus_Function_3();
break;
case 0x05:
Modbus_Function_5();
break;
case 0x02:
Modbus_Function_2();
break;
case 0x10:
Modbus_Function_16();
break;
default:
{
Com0_Send_Data_Buffer[1]=0xFF;
Com0_Send_Data_Buffer[2]=2;
Com0_Send_Data_Bytes=5;
Com0_Send_Data_Buffer[3]=0x00;
Com0_Send_Data_Buffer[4]=0x06;
}
}
}
else
{
////show error!
Com0_Send_Data_Buffer[1]=0xFF;
Com0_Send_Data_Buffer[2]=2;
Com0_Send_Data_Bytes=5;
Com0_Send_Data_Buffer[3]=0x00;
Com0_Send_Data_Buffer[4]=0x07;
}
crcresult= getCRC16(Com0_Send_Data_Buffer,Com0_Send_Data_Bytes);
Com0_Send_Data_Buffer[Com0_Send_Data_Bytes]=crcresult & 0xff;
Com0_Send_Data_Buffer[Com0_Send_Data_Bytes+1]=(crcresult >> 8) & 0xff;
Com0_Send_Data_Bytes=Com0_Send_Data_Bytes+2;
Com0_Send_Data_Pointer=Com0_Send_Data_Buffer;
UDR0=*Com0_Send_Data_Pointer;
}
关键字:AVR MODBUS程序
引用地址:
AVR的部分MODBUS程序
推荐阅读最新更新时间:2024-03-16 15:16
AVR单片机IO的使用方法详细资料概述
主要内容详细介绍的是AVR单片机IO的使用方法详细资料 AVR单片机寄存器 DDRx PORTx PINx 与对应IO端口之间的关系(x代表某个端口,如A端口、B端口等) 下表以端口B的第2位PB2为例子加以说明,并且假设PB2为悬空状态 DDRB.2 PORTB.2 读取PINB.2的结果 引脚PB2的状态 1 1 1 PB2推挽输出 1 1 0 0 PB2推挽输出 0 0 1 1 PB2弱上拉,可作输入 0 0 × PB2高阻抗,可作输入 读取PINB.2时,就是读取PB2引脚的实际电平, 如果PB2直接接VCC,那么任何时候读取PINB.2的结果都是1 如果PB2直接接
[单片机]
AVR Studio 的使用注意
AVR单片机最常用的集成开发环境就是AVR Studio和ICCAVR了,AVR Studio是ATMEL公司自己开发的编译环境,但是只支持汇编语言的开发。现在的版本已经出到AVR Studio5.0 ,但是好像要100M左右,很多研发的都是在使用AVR Studio4.0版本的吧。相对于C语言来说,就要安装winAVR和AVR Studio共同组成C语言编译环境了。AVR Studio头文件有自己的延迟函数。#include uitl/delay.h 有毫秒_delay_ms()和微妙_delay_us()两个子函数,可以在其他函数中调用这两个函数,但是使用这两个函数的时候特别要注意在AVR Studio中设置编译对象的晶振和优
[单片机]
AVR 硬件操作库函数
/********************************************************************* 目 的: 建立AVR的硬件提取库,增加各类补丁,方便系统程序移植 目标系统: 基于AVR单片机 应用软件: ICCAVR 版 本: Version 1.0 *********************************************************************/ /*010101
[单片机]
Atmel推出QTouch Suite捆绑式MCU工具包
爱特梅尔公司(Atmel Corporation) 宣布,爱特梅尔的QTouch Suite将以更多的功能让第三方的CAD开发商更容易使用 QTouch技术。利用 QTouch Suite和CAD 软件工具,设计工程师现在可在做示意图、PCB布局设计和原型阶段时,简易增加触摸按键、触摸滑块和触摸滑轮。此外,设计工程师可以使用爱特梅尔主导行业的 AVR 微控制器,开发具触控功能之低耗电应用。
设计工程师不断要求集成包括更多功能的软件方案,使他们能更迅速地开发证明概念的设计。通过在开发者软件中直接提供爱特梅尔的 QTouch Studio,设计工程师现在可以有一个完善的触控选择库,触摸按键、触摸滑块和触摸滑
[嵌入式]
icc avr LCD1602显示屏程序
入口参数说明: // control port //#define SET_RS sbi(PORTB,5) //#define CLR_RS cbi(PORTB,5) //#define OUT_RS sbi(DDRB,5) //#define SET_RW sbi(PORTB,6) //#define CLR_RW cbi(PORTB,6) //#define OUT_RW sbi(DDRB,6) //#define SET_E sbi(PORTB,7) //#define CLR_E cbi(PORTB,7) //#define OUT_E sbi(DDRB,7) // data port //#define SET_D4
[嵌入式]
AVR单片机教程——按键状态
今天我们来讲按键。开发板的右下角有4个按键,按下会有明显的“咔嗒”声。如何检测按键是否被按下呢?首先要把按键或直接或间接地连接到单片机上。与之前使用的4个LED不同,4个按键没有全部连接到单片机上——左边2个是连接的,右边2个通过按键上方标有B2、B3的接口引出(从左到右分别为B0、B1、B2和B3)。如果要使用B2、B3,要用杜邦线连接到16个单片机引出针脚上。 开发板库中与按键相关的函数定义在 ee1/button.h ,这里是库函数手册。值得一提的是1.1版本的库中,换用枚举类型表示按键等设备,不再使用整数与宏定义(但用整数也是兼容的)。在Atmel Studio 7.0中写代码时,编辑器会提示函数接口,可以根据参数类型
[单片机]
AVR单片机汇编器伪指令
伪指令不属于 单片机 的指令系统,而是由汇编器提供的指令,用于调整 存储器 中程序的位置、定义宏、初始化存储器等。AVR单片机的汇编器共提供18条伪指令(见附表)。 其中,ORG、DB、DW、EQU读者比较熟悉,这里不再赘述。下面对部分伪指令加以说明。 BYTE-保存单字节数据到SRAM中。BYTE伪指令仅用在数据存储器。为提供数据保存的位置,在BYTE前应有标号。在由CSEG、ESEG定义的代码段和E2PROM段中不能使用BYTE伪指令。 格式LABEL:.BYTE表达式 CSEG-定义程序存储器代码段的起始位置一个汇编文件可以包括若干个代码段,汇编时这些代码段被连成一个代码段。在代码
[单片机]
AVR单片机驱动无源蜂鸣器
内部1 M晶振。 定时器实险,周期信号驱动无源蜂鸣器,些实验基于定时器的CTC模式,由硬件产生频率信号。 程序中实现单一频率的周期性提示音。 程序采用单任务方式,软件延时。 */ #include "iom16v.h" /*延时函数*/ void delay_ms(unsigned char i) { unsigned char a, b; for (a = 1; a i; a++) { for (b = 1; b; b++) { ; } } } void main(void) { unsigned char i; DDRA = 0x00; /*方向输入*/ PORTA = 0xFF; /*打开上拉*/
[单片机]