登录
|
注册会员
开启辅助访问
设为首页
收藏本站
扫一扫关注官方微信
论坛
BBS
M币充值
M currency prepaid phone
M币获取
附件中心
搜索
search
全新论坛MCU智学网上线,欢迎访问新论坛!稀缺资源、技术干货、参考设计、原厂资料尽在MCU智学网
MCU资讯论坛
»
论坛
›
单片机论坛
›
AVR单片机论坛
›
UART多机通讯模式
更新自动建库工具PCB Footprint Expert 2023.13 Pro / Library Expert 破解版
UART多机通讯模式
[复制链接]
3992
0
慧***
超级版主
发表于 2010-5-25 23:56:55
|
查看全部
|
阅读模式
本文包含原理图、PCB、源代码、封装库、中英文PDF等资源
您需要
登录
才可以下载或查看,没有帐号?
注册会员
x
主机MEGA16L,代码如下
#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
unsigned char data;
unsigned char timerl;
unsigned char timerh;
unsigned char time,rr;
unsigned char sendbuf[10];
unsigned char recbuf[10];
uchar addr,fun,message;
uchar realaddr,realfun,keepaddr,al
ARM
,realalarm; // for ²¦Â뿪¹Ø
void delay(unsigned char i)
{
for(timerl=0;timerl<i;);
}
void port_init(void)
{
PORTA = 0x3F;
DDRA = 0x00;
PORTB |= 0x08; // 485
DDRB |= 0x08;
PORTC = 0x00; //m103 output only
DDRC = 0xFF;
PORTD = 0xC0;
DDRD = 0x30;
}
//TIMER0 initialize - prescale:64
// WGM: Normal
// desired value: 1mSec
// actual value: 1.000mSec (0.0%)
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x83; //set count
TCCR0 = 0x03; //start timer
}
#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
TCNT0 = 0x83; //reload counter value
timerl++;
timerh++;
}
//TIMER1 initialize - prescale:1024
// WGM: 0) Normal, TOP=0xFFFF
// desired value: 1Sec
// actual value: 1.000Sec (0.0%)
void timer1_init(void)
{
TCCR1B = 0x00; //stop
TCNT1H = 0xE1; //setup
TCNT1L = 0x7C;
TCCR1A = 0x00;
TCCR1B = 0x05; //start Timer
}
#pragma interrupt_handler timer1_ovf_isr:9
void timer1_ovf_isr(void)
{
//TIMER1 has overflowed
TCNT1H = 0xE1; //reload counter high value
TCNT1L = 0x7C; //reload counter low value
time++;
}
//UART0 initialize
// desired baud rate: 19200
// actual: baud rate:19231 (0.2%)
// char size: 9 bit
// parity: Disabled
void uart0_init(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UCSRC = BIT(URSEL) | 0x06;
UBRRL = 0x19; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
UCSRB = 0xDC;
}
#pragma interrupt_handler uart0_rx_isr:12
void uart0_rx_isr(void)
{
//uart has received a character in UDR
}
#pragma interrupt_handler uart0_tx_isr:14
void uart0_tx_isr(void)
{
unsigned char i;
rr ++;
if(rr < 4){
// for(i=0;i<100;i++);
UCSRB &= ~(1<<TXB8);//
UDR = sendbuf[rr];
}
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
timer0_init();
timer1_init();
uart0_init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x05; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
void ReadSwitch(){
unsigned char i;
realaddr = 0;
realfun = 0;
PORTB &= 0xF8;
DDRB &= 0xF8;
DDRB |= 0x01;
for(i=0; i<40; i++);
if(!(PINA & 0x20)) realaddr |= 0x01;
if(!(PINA & 0x10)) realaddr |= 0x02;
if(!(PINA & 0x08)) realaddr |= 0x04;
if(!(PINA & 0x04)) realaddr |= 0x08;
if(!(PINA & 0x02)) realaddr |= 0x10;
if(!(PINA & 0x01)) realaddr |= 0x20;
DDRB &= 0xF8;
DDRB |= 0x02;
for(i=0; i<40; i++);
if(!(PINA & 0x01)) realaddr |= 0x40;
if(!(PINA & 0x02)) realaddr |= 0x80;
if(!(PINA & 0x04)) realfun |= 0x01;
if(!(PINA & 0x08)) realfun |= 0x02;
if(!(PINA & 0x10)) realfun |= 0x04;
if(!(PINA & 0x20)) realfun |= 0x08;
DDRB &= 0xF8;
DDRB |= 0x04;
for(i=0; i<40; i++);
if(!(PINA & 0x08)) realfun |= 0x40;
if(!(PINA & 0x10)) realfun |= 0x20;
if(!(PINA & 0x20)) realfun |= 0x10;
PORTB |= 0x01;
DDRB &= 0xF8;
DDRB |= 0x01;
}
unsigned char checksum()
{
return (sendbuf[0]+sendbuf[1]+sendbuf[2]);
}
void main(void)
{
unsigned char i;
init_devices();
timerl = 0;
timerh = 0;
time = 0;
for(;;){
if(timerl > 200){
PORTB ^= 0x01;
timerl = 0;
ReadSwitch();
if(realfun & 0x01){
sendbuf[0]=realaddr;
sendbuf[1]=0x77;
sendbuf[2]='1';
sendbuf[3]= checksum();
rr = 0;
UCSRB |= (1<<TXB8);
UDR = realaddr;
}
if(realfun & 0x02){
sendbuf[0]=realaddr;
sendbuf[1]=0x77;
sendbuf[2]='2';
sendbuf[3]= checksum();
rr = 0;
UCSRB |= (1<<TXB8);
UDR = realaddr;
}
if(realfun & 0x04){
sendbuf[0]=realaddr;
sendbuf[1]=0x77;
sendbuf[2]='3';
sendbuf[3]= checksum();
rr = 0;
UCSRB |= (1<<TXB8);
UDR = realaddr;
}
if(realfun & 0x08){
sendbuf[0]=realaddr;
sendbuf[1]=0x77;
sendbuf[2]='4';
sendbuf[3]= checksum();
rr = 0;
UCSRB |= (1<<TXB8);
UDR = realaddr;
}
if(realfun & 0x10){
sendbuf[0]= realaddr;
sendbuf[1]= 0x77;
sendbuf[2]= 'F';
sendbuf[3]= checksum();
rr = 0;
UCSRB |= (1<<TXB8);
UDR = realaddr;
}
if(realfun & 0x40){
sendbuf[0]=realaddr;
sendbuf[1]=0x77;
sendbuf[2]=0x88; sendbuf[3]= checksum();
rr = 0;
UCSRB |= (1<<TXB8);
UDR = realaddr;
}
if(realfun & 0x20){
sendbuf[0]=realaddr;
sendbuf[1]=0x88;
sendbuf[2]='8';
sendbuf[3]= checksum();
rr = 0;
UCSRB |= (1<<TXB8);
UDR = realaddr;
}
}
}
}
复制代码
多机通讯与普通的USART通讯差不多,只不过注意几点:
1,需在复位时将UCSRA寄存器中的MPCM位置1
2,上位机发送地址数据时将第九位置1,这样一来,所有的从机都能通过中断接收到此数据啦各个从机判断接收到的数据是否与自己的地址相符,不符的返回,符合的(只能有1台符合)将MPCM位置0,以便正常的接收发给自己的数据.这些数据的第九位必须为0.其他的从机不会对这些数据产生中断.从而实现多机通讯.
上位机发送 UCSRB |= (1<<TXB8);及第九位数据是1的时候,从机能够能够产生中断,如果第九位0,则从机将数据忽略。如果你发的数据帧:
地址+数据1+数据2+...
你可以在从机接收到地址数据后,与本机的地址比较,如果相同。说明是发给本机的指令,你可以在中断中将本设置普通的数据模式,用以接收后面的数据。
上面的MEGA16程序是完整的程序,能够在ICC
AVR
上运行通过的。
下位机是MEGA8
void uart0_init_mulmodel(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x01; //mul. processor
UCSRC = BIT(URSEL) | 0x06;
UBRRL = 0x19; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
UCSRB = 0x94; //9 bit data
}
void uart0_init_normodel(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00; //normal model
UCSRC = BIT(URSEL) | 0x06;
UBRRL = 0x19; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
UCSRB = 0x94; //9 bit data
}
#pragma interrupt_handler uart0_rx_isr:12
void uart0_rx_isr(void)
{
//uart has received a character in UDR
rrr[rr] = UDR;
rr++;
receivetask();
}
//数据接收处理函数
void R_KeLi(void)
{
kelitimer = 0;
switch(rr){
case 1:
if(rrr[0] == addr){//判断地址是否与本机地址相等
uart0_init_normodel();//如果相等,将本设置位普通模式来接收后面的数据,如果没有这句,后面的数据(第九位为0)将被忽略
}
else{
rr = 0;
}
break;
}
}
复制代码
举报
回复
返回列表
*
滑块验证:
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
注册会员
本版积分规则
发表回复
回帖后跳转到最后一页
回复
转播
评分
分享
打开支付宝扫一扫,最高立得1212元红包
搜索
本版
帖子
用户
热搜:
传感器
51串口程序
电子管放大器
夾式電表
夾式電流
Mentor论坛
打印机
版块推荐
百宝箱
My 布拉格
无边框Z9
Z9Max
Z9mini
nubia动态
问题 & 建议
资源分享
爱拍
同城会
牛仔生活
查看论坛所有版块>>
每日签到
论坛任务
摄影技巧
跳蚤市场
互助问答
论坛导读
申请内测
红包中心
每日摇一摇
活动中心
网站地图
官方旗舰店
图文热点
I2C通信接口段码液晶驱动芯片VK2C21C SOP20
产品品牌:永嘉微电/VINKA 产品型号:VK2C21C 封装形式:SOP20 概述 VK2C21C是
VK2C21B SOP24高抗干扰LCD液晶段码驱动芯片
产品品牌:永嘉微电/VINKA 产品型号:VK2C21B 封装形式:SOP24 概述 VK2C2B是一
低成本、高性能、带EEPROM了解一下
无锡矽杰微电子的XCE855E 是一颗带 EEPROM 的 8 位单片机,专为多 IO 产品的应用而设
工控仪表/水电气表LCD驱动/抗干扰液晶段码
产品品牌:永嘉微电/VINKA 产品型号:VK2C21A 封装形式:SOP28 概述 VK2C21是一
为什么电动车会着火?原因是什么?电动车充
其实电动车起火的新闻我们也不是第一次看到了,让很多人对电动车的安全性产生质疑,但
更多
精华推荐
I2C通信接口段码液晶驱动芯片VK2C21C SOP20
VK2C21B SOP24高抗干扰LCD液晶段码驱动芯片
低成本、高性能、带EEPROM了解一下
工控仪表/水电气表LCD驱动/抗干扰液晶段码
软件模拟2812通信协议导致的种种问题,你遇
适用于电子鞭炮、电子蜡烛灯等方案的单片机
为什么电动车会着火?原因是什么?电动车充
性价比超高的国产单片机了解一下
更多
社区学堂
I2C通信接口段码液晶驱动芯片VK2C21C S
VK2C21B SOP24高抗干扰LCD液晶段码驱动
I2C通信接口段码液晶驱动芯片VK2C21C SOP20
产品品牌:永嘉微电/VINKA 产品型号:VK2C21C 封装形式:SOP20 概述 VK2C21C是
VK2C21B SOP24高抗干扰LCD液晶段码驱动芯片
产品品牌:永嘉微电/VINKA 产品型号:VK2C21B 封装形式:SOP24 概述 VK2C2B是一
低成本、高性能、带EEPROM了解一下
无锡矽杰微电子的XCE855E 是一颗带 EEPROM 的 8 位单片机,专为多 IO 产品的应用而设
更多
客服中心
QQ:187196467
服务时间:周一至周日 8:30-20:30
在线客服
客服微博
产品咨询
售后中心
关注我们
关于我们
关于我们
友情链接
联系我们
帮助中心
网友中心
购买须知
支付方式
服务支持
资源下载
售后服务
定制流程
关注我们
官方微博
官方空间
官方微信
QQ:187196467
周一到周日 8:30-22:00 (全年无休)
7 x 24小时在线客服
手机版
Powered by
MCUZX!
X3.4 © 2008-2015
MCU资讯论坛
版权所有
京ICP备18035221号-2
客服QQ: 187196467
技术支持:
MCU资讯论坛
|
网站地图
快速回复
返回顶部
返回列表