📄 shiyan5.c
字号:
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <inttypes.h>
#include <pgmspace.h>
char global_uart1_data=0;
char command_send[17]=":0E0300050001A2\r\n";
char data_receive[20];
int ii=0;
// ":" 地址 命令 寄存器地址 寄存器数量 校验 回车 换行
//******************************延时子程序*****************************************
void delay_us(uint16_t u) //延时2us左右,delay(240)=100us;
{
while(u)
{
u--;
}
}
// 延时nms
void delay_ms(uint16_t m)
{
uint16_t i;
for(i=0;i<m;i++)
{
delay_us(2400); //延时1ms
}
}
//延时ns
void delay_s(uint16_t n)
{
uint16_t j;
for(j=0;j<n;j++)
{
delay_ms(1000); //延时1s
}
}
void usart1_init(void)
{
UBRR1H=0x00;
UBRR1L=0x19;//设置波特率为2400bit/s,当晶振频率为7.3728M时
UCSR1A=0X00;
UCSR1B=(1<<RXEN1)|(1<<TXEN1)|(1<<RXCIE1);//接收允许,发送允许,接收中断使能
UCSR1C=(1<<UPM11)|(0<<UPM10)|(1<<UCSZ11);//异步传输,7个数据位,1个停止位,偶校验(根据MODBUS ASCII协议)
sbi(DDRD,PD4);//CS485为输出,控制max485的发送和接收
cbi(PORTD,PD4);//max485接收使能
}
void sendchar(char data)//发送
{
sbi(PORTD,PD4);//控制max485的发送
if(!(UCSR1A&(1<<UDRE1)))//等待UDRE被置位,否则对数据寄存器UDR的写操作将被忽略
{
UCSR1A|=(1<<UDRE1);
}
while(!(UCSR1A&(1<<UDRE1)))//等待发送缓冲器空
{;}
UDR1=data;//发送数据
while(!(UCSR1A&(1<<TXC1))){;}
//loop_until_bit_is_set(UCSR1A,TXC1);//查询发送是否结束
UCSR1A=UCSR1A|(1<<TXC1);//因为没有使用发送结束中断,所以通过置数将TXC清零
cbi(PORTD,PD4);//改为接收状态
return;
}
SIGNAL(SIG_UART1_RECV)//当RXCIE1=1,SREG=0X80,接收结束时有RXC1也为1
{
cli();
global_uart1_data=UDR1;
data_receive[ii]=global_uart1_data;
ii++;
if(ii>14)
{
ii=0;
}
sei();
}
int lrc_check(char *p,int length)
{
int lrc=0;
int i=0;
for(i=1;i<=length;i++)
lrc=lrc+*(p+i);
lrc=lrc%256;
lrc=0xff-lrc;
lrc++;
return lrc;
}
int main()
{ char *pointer;
int i;
char n;
pointer=command_send;
int lrc_check_value;
sbi(DDRD,PD4);//配置CS485为输出
cbi(PORTD,PD4);//控制max485为接收
sei();
usart1_init();
delay_ms(5);
lrc_check_value=lrc_check(command_send,12);
for(i=0;i<=16;i++)
{sendchar(*pointer);
n=*pointer;
pointer++;}
while(1)
{;}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -