登录
|
注册会员
开启辅助访问
设为首页
收藏本站
扫一扫关注官方微信
论坛
BBS
M币充值
M currency prepaid phone
M币获取
附件中心
搜索
search
全新论坛MCU智学网上线,欢迎访问新论坛!稀缺资源、技术干货、参考设计、原厂资料尽在MCU智学网
MCU资讯论坛
»
论坛
›
单片机论坛
›
AVR单片机论坛
›
串口实验
更新自动建库工具PCB Footprint Expert 2023.13 Pro / Library Expert 破解版
串口实验
[复制链接]
2629
0
慧***
超级版主
发表于 2010-5-9 21:36:30
|
查看全部
|
阅读模式
本文包含原理图、PCB、源代码、封装库、中英文PDF等资源
您需要
登录
才可以下载或查看,没有帐号?
注册会员
x
本程序简单的示范了如何使用ATMEGA16的USART
USART的设置
波特率的计算
发送采用查询方式
接收采用中断方式
除非有特殊格式要求,否则不建议使用 printf函数库,该函数会耗用3~6KB程序空间
这里的应用比较简单,所以自己编写了put_c/put_s函数。
出于简化程序考虑,各种数据没有对外输出,学习时建议使用JTAG ICE硬件仿真器
#include <
AVR
/io.h>
#include <avr/delay.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
/*
注: 内部函数_delay_ms() 最高延时 262.144mS@1MHz
为了使 _delay_ms()函数的延时正确,须在makefile中设定F_CPU为实际的系统时钟频
本范例为7.3728MHz外部石英晶体振荡器 即 F_CPU=7372800
因为7.3728MHz能生成多种标准的通讯波特率。
如果使用其他系统时钟频率,注意 波特率误差不要超过 +/-1%.
做USART通讯时,除非你掌握了校准技术,否则请不要使用内部/外部RC振荡器
*/
//管脚定义
#define PIN_RXD 0 //PD0 RXD
#define PIN_TXD 1 //PD1 TXD
#define LED0 0 //PB0
#define LED1 1 //PB1
#define LED2 3 //PB3
//常量定义
#define BAUDRATE 9600 //波特率
//#define F_CPU 7372800 //这个已经在makefile里面定义了
//宏定义
#define LED0_ON() PORTB|= (1<<LED0) //输出高电平,灯亮
#define LED0_OFF() PORTB&=~(1<<LED0) //输出低电平,灯灭
#define LED1_ON() PORTB|= (1<<LED1)
#define LED1_OFF() PORTB&=~(1<<LED1)
#define LED2_ON() PORTB|= (1<<LED2)
#define LED2_OFF() PORTB&=~(1<<LED2)
//51系列的高电平输出能力很弱,低电平也仅能点亮LED.所以常见输出低电平才灯亮的接法。
//AVR芯片的高低驱动能力都很强,甚至能推动8字数码管的公共极,怎么接都没问题。
//全局变量
//如果变量会在中断服务程序中被修改,须加volatile限定
volatile unsigned char FLAG; //按键标志
volatile unsigned char PC_COMMAND; //PC发出的当前命令
volatile unsigned char RX_BUFFER[16]; //存放接收数据的数组
volatile unsigned char RX_index; //存放接收数据的个数
//仿真时在watch窗口,监控这些变量。
void put_c(unsigned char c) //发送采用查询方式
{
while( !(UCSRA & (1<<UDRE)) );
UDR=c;
}
void put_s(unsigned char *ptr)
{
while (*ptr)
{
put_c(*ptr++);
}
put_c(0x0D);
put_c(0x0A); //结尾发送回车换行
}
SIGNAL(SIG_USART_RECV) //串口接收中断服务程序
{
PC_COMMAND=UDR;
switch(PC_COMMAND)
{
case '0': //0x30 ASCII '0'
LED0_ON();
put_s("用户输入0#指令");
break;
case '1':
LED1_ON();
put_s("用户输入1#指令");
break;
case '2':
LED0_OFF();
LED1_OFF();
FLAG=!FLAG;
put_s("用户输入2#指令");
break;
default:
put_s("用户输入的指令无效!");
break;
}
/*
注意,使用put_s函数发送数据需要一定的时间,如果输入数据的速度过高将会导致数据丢失
所以,一般建议中断服务程序的处理时间尽量的短,只做采集数据和设标志位,命令的处理交由主程序来完成
这里只是示范简单的命令处理
*/
RX_BUFFER[RX_index]=PC_COMMAND; //保存数据到数组里面
RX_index++;
if (RX_index>=16) RX_index=0; //防止数组溢出
}
void init_USART(void)//USART 初始化
{
//USART 9600 8, n,1 PC上位机软件(超级终端等)也要设成同样的设置才能通讯
UCSRC = (1<<URSEL) | 0x06;
//异步,8位数据,无奇偶校验,一个停止位,无倍速
/*
UBRRH与UCSRC共用I/O 地址。因此访问该地址时需注意以下问题。
写访问
当在该地址执行写访问时, USART 寄存器选择位(URSEL)控制被写入的寄存器。
若URSEL为0,对UBRRH值更新;若URSEL为1,对UCSRC设置更新
读访问
对UBRRH 或UCSRC 寄存器的读访问则较为复杂。但在大多数应用中,基本不需要读这些寄存器
没有UBRR这个16位寄存器,因为UBRRL(0x09)/UBRRH(0x20)的地址不连续,而且UBRRH跟UCSRC共用地址
*/
//U2X=0时的公式计算
UBRRL= (F_CPU/BAUDRATE/16-1)%256;
UBRRH= (F_CPU/BAUDRATE/16-1)/256;
//U2X=1时的公式计算
//UBRRL= (F_CPU/BAUDRATE/8-1)%256;
//UBRRH= (F_CPU/BAUDRATE/8-1)/256;
//也可根据数据手册的[波特率设置的例子]查得
//UBRRL = 0x2F; //set baud rate lo
//UBRRH = 0x00; //set baud rate hi
UCSRA = 0x00;
UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
//使能接收中断,使能接收,使能发送
}
void pro_coammand(void) //多字节命令的处理程序
{
unsigned char i;
if (RX_index>=10)
{
UCSRB&= ~(1<<RXCIE); //关断USART接收中断
put_c(0x0D);
put_c(0x0A); //发送回车换行
put_s("Hello! 你之前输入的命令列表是:");
for (i=0;i<RX_index;i++) put_c(RX_BUFFER[i]);
put_c(0x0D);
put_c(0x0A);
put_c(0x0D);
put_c(0x0A); //发送回车换行
RX_index=0; //清零
UCSRB|= (1<<RXCIE); //打开USART接收中断
}
}
int main(void)
{
//上电默认DDRx=0x00,PORTx=0x00 输入,无上拉电阻
PORTA =0xFF; //不用的管脚使能内部上拉电阻。
PORTC =0xFF;
DDRB = (1<<LED2)|(1<<LED1)|(1<<LED0); //输出
PORTB =~((1<<LED2)|(1<<LED1)|(1<<LED0)); //低电平,灯灭
DDRD =(1<<PIN_TXD); //TXD为输出
PORTD =0xFF;
FLAG=0;
init_USART();
put_s("你好!");
put_s("这是一个简单的串口实验程序");
put_s("你可以在电脑上的超级终端程按下[0][1][2]按键,模拟用户板上的按键操作");
sei(); //使能全局中断
while (1)
{
while (FLAG==0) pro_coammand();
LED2_ON(); //如果FLAG不加volatile限定(即has_volatile=0),程序将永远都运行不到这里。
while (FLAG!=0) pro_coammand();
LED2_OFF();
}
}
复制代码
程序运行效果
PC使用超级终端或SSCOM32串口调试程序,发送ASCII码的简单方法就是直接按下对应的按键
例如 字符'0',即0x30 ,按下键盘上的[0]即可
按下按键[0],LED0亮。
按下按键[1],LED1亮。
按下按键[2],LED0/1都熄灭, LED2是根据按键[2]的顺序来亮灭,是个乒乓键
串口实验范例.rar
(32.05 KB, 下载次数: 0)
2010-5-9 21:36 上传
点击文件名下载附件
举报
回复
返回列表
*
滑块验证:
高级模式
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资讯论坛
|
网站地图
快速回复
返回顶部
返回列表