一、实验目的

1. 理解单片机串口的工作原理。

2. 掌握串口的编程方法。

二、实验内容

1. 验证课堂例题

编译下载运行课堂例题——“串口发送中断”(usart_ex1)和“串口接收中断”(usart_ex2),查看运行结果。理解程序的编程思想和程序执行过程。

2. 设计程序

参考上述例题的电路和编程思路,自行设计电路,包括六位数码管、4*4矩阵键盘、串口电路,完成按键定义值的数码管显示和串口通信,串口接收到的字符在数码管显示。

具体要求如下:

(1)上电复位后,数码管显示“000000”,单片机通过串口发送“Hello-Usart”握手信息;

(2)按下键盘数字键,相应数字字符在数码管最后一位显示,同时该按键的定义值以字符格式发送给串口;

(3)上位机向单片机发送’0’~’9’字符,单片机将接收到的字符在数码管最高位进行显示;

(4)要求串口发送不使用中断,串口接收使用中断。

在设计报告中,需进行总体设计思路描述,给出所涉及到的主程序、中断程序、关键功能子函数的流程图和设计代码。描述程序调试结果及出现的问题。

三、实验结果

1. 在下方贴出使用Proteus绘制的电路原理图。

图4-1 实验电路图

2. 描述所设计程序的总体设计思路

本程序分为主函数,串口发送函数,串口中断接收函数,数码管显示函数,按键检测与处理函数。

通过开启串口的接收中断,来触发中断回调函数。通过在串口中断回调函数中读取串口接收寄存器的数据来为数码管显示数组赋值。并且设置一个串口发送函数,将串口需要的发送的数据写入串口发送寄存器中,就可以实现将数据通过串口发送。

最后只需在主函数中通过检测按键是否按下来对数码管数组做相应的处理,并将要显示的数据通过串口发送出去。并且根据数码管数组刷新数码管即可。

3. 根据所设计的程序顶层结构,对主函数、中断函数、关键功能子函数的设计思路进行简单描述,并给出各函数的流程图

主函数:首先对需要使用到的IO口做相应的初始化,之后对串口进行初始化,并开启串口接收中断。在发送握手信息之后,在主循环中判断是否有按键按下,如果有按键按下,就对数码管显示数组赋值,并将按下的键对应的数据利用串口发送。最后刷新数目管。

串口发送函数:等待串口发送寄存器为空,在串口发送寄存器为空之后为串口缓冲区写入一个字节的数据。

串口接收中断回调函数:读取串口接收缓冲寄存器中的值,并将该值赋值给数码管显示数组。

按键处理函数:判断是否有按键按下,如果有按键按下的话,根据该按键对应的值赋值给串口待发送数据(这里需要注意的是串口发送的数据应该是ASCII码,所以对于数字而言需要再加上0x30),同时也根据该按键对应的值对返回值赋值。

4. 给出(3)中相关函数的实现代码(在ICCAVR中进行编程,以截屏贴图方式放入实验报告中,注意规范性,必须加注释)

#include <iom16v.h>
#include <macros.h>//宏定义
#define  uchar unsigned char
#define  uint  unsigned int//全局变量定义
//数码管使用
uchar const DuanXuan[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共阴级数码管显示0-F
uchar const WeiXuan[6]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};//从左到右第0-5位数码管
uchar LEDBuf[6]={0,0,0,0,0,0};//存放数码管显示数据,0-9数字格式
uchar send_char[11]={'H','e','l','l','o','-','U','s','a','r','t'};
int i=0;
uchar send_key;
uchar rx_data;//函数声明
void delay(uint ms);             //延时函数
void LEDshow(uchar LEDBuf[6]);   //数码管显示函数
uchar key_press();               //按键检测函数
uchar key_where();               //按键定位函数
void uart_init();
void uart_send_1byte(uchar send_char);//**************************************************************************************
//主函数
//**************************************************************************************
void main(void)
{    //初始化//初始化数码管DDRC|=BIT(1);            //PC3设置为输出DDRC|=BIT(2);            //PC4设置为输出DDRB=0XFF;               //PB口设置为输出//初始化键盘DDRA=0x0F;                //高4位为输入,低4位为输出PORTA&=0xF0;         //低4位输出低电平CLI();                    //关总断 uart_init();          //串口初始化SEI();               //开总中断for(i=0;i<11;i++)               //循环发送握手信息uart_send_1byte(send_char[i]);    //发送握手信息while(1){if(key_press())            //判断键盘中是否有按键按下{         LEDBuf[5]=key_where(); //按下后显示在第五位uart_send_1byte(send_key);}LEDshow(LEDBuf);              //数码管刷新}
}//**************************************************************************************
//通用功能子函数
//**************************************************************************************//**************************************************************************************
//函数名:延时函数
//输入参数:ms
//**************************************************************************************
void delay(uint ms)
{uint p,q;for(p=0;p<ms;p++){for(q=0;q<1141;q++);}
}         //**************************************************************************************
//数码管模块子函数
//**************************************************************************************//**************************************************************************************
//函数名:LEDshow
//功能:在数码管上显示出对应的数字。0-5位数码管显示数据放在LEDBuf[]中,存放0-9数字格式
//输入参数:LEDBuf[]每个元素对应6位数码管每位的显示数字(0-F)
//**************************************************************************************void LEDshow(uchar LEDBuf[6])
{   uchar i;for(i=0;i<6;i++)              //循环扫描一次{   //数码管位选程序PORTB=WeiXuan[i];          //选择第i位数码管PORTC|=BIT(PC2);             //PA4输出高电平,位选端拉高PORTC&=~BIT(PC2);           //PA4输出低电平,位选端拉低,位选锁存//数码管段选程序 PORTB=DuanXuan[LEDBuf[i]];   //输出段选PORTC|=BIT(PC1);         //PA3输出高电平,段选端拉高PORTC&=~BIT(PC1);           //PA3输出低电平,段选端拉低,段选锁存  delay(1);}
}//**************************************************************************************
//矩阵键盘模块子函数
//**************************************************************************************//**************************************************************************************
//函数名:key_press
//功能:检测是否有低电平出现,来判断是否有按键按下
//返回值:1-有键按下,0-无键按下
//**************************************************************************************
uchar key_press(void)
{uchar temp;PORTA=0xF0;                //高4位输出高电平,低4位输出低电平temp=PINA;               //读取PA口if(temp==0xF0)         //输入端未出现低电平(没有按键按下) {return 0;            //输出0}else                  //有按键按下{         return 1;          //输出1}
}//**************************************************************************************
//函数名:key_where
//功能:读行线列线电平,根据按键键值进行定位
//返回值:按键代表的十六进制数字(0-F)
//**************************************************************************************
uchar key_where(void)
{uchar Code;            //存储PINC值,即引脚读入值uchar Hang=0X7F;    //行线输出值uchar Lie;           //列线值,4位 delay(10);if(key_press())       //调用按键检测函数{do{Hang=((Hang<<1)|(Hang>>7));  //循环左移,每一次只输出一个低电平PORTA=Hang;               //低四位在C口输出,行线逐位输出0        Code=PINA; Lie=Code&0xF0;            //读取key高四位(列线)}while(Lie==0xF0);          //列线出现全1为不在该行,列线出现0说明该键在该行while(key_press());         //等待按键松开 switch(Code)                //有16种情况{case 0xEE:               //1110 1110  第1行第1列(1,1){Code=0x1;     //显示1send_key=0x31;break;}case 0xDE:             //(1,2){ Code=0x2;send_key=0x32;break; }case 0xBE:             //(1,3){Code=0x3;send_key=0x33;break;}case 0x7E:             //(1,4){Code=0xA;send_key=0x41;break;}case 0xED:             //(2,1){Code=0x4;send_key=0x34;break;}case 0xDD:             //(2,2){Code=0x5;send_key=0x35;break;}case 0xBD:             //(2,3){Code=0x6;send_key=0x36;break;}case 0x7D:             //(2,4){Code=0xB;send_key=0x42;break;}case 0xEB:             //(3,1){Code=0x7;send_key=0x37;break;}case 0xDB:             //(3,2){Code=0x8;send_key=0x38;break;}case 0xBB:             //(3,3){Code=0x9;send_key=0x39;break;}case 0x7B:             //(3,4){Code=0xC;send_key=0x43;break;}case 0xE7:             //(4,1){Code=0xE;send_key=0x2A;break;}case 0xD7:             //(4,2){Code=0x0;send_key=0x30;break;}case 0xB7:             //(4,3){ Code=0xF;send_key=0x23;break;}case 0x77:             //(4,4){Code=0xD;send_key=0x44;break;}default:Code=16;        }}else//无按键按下{Code=16;}return Code;
}//**************************************************************************************
//函数名:uart_init
//功能:串口初始化
//**************************************************************************************
void uart_init(void)
{UCSRB=0x00;           //禁止发送器和接收器,禁止串口中断UCSRA=0b00100000;     //各标志位清零,双机通信模式,无加速波特率UCSRC=0b10000110;  //异步模式,无奇偶校验,1位停止位,8位数据位UBRRL=0x33;           //设置波特率9600bps,fosc=8MHz,UBRR=fosc/(16*baud)-1UBRRH=0x00;UCSRB=0x98;        //使能接收中断,使能发送器和接收器
}//**************************************************************************************
//函数名:uart_send_1byte
//功能:串口发送函数
//**************************************************************************************
void uart_send_1byte(uchar send_char)
{while(!(UCSRA&(1<<UDRE)));   //等待发送缓冲器为空UDR=send_char;              //向发送缓冲器写入1byte数据,启动发送
}//**************************************************************************************
//函数名:uart_rx_isr
//功能:串口接收中断回调函数。
//**************************************************************************************
#pragma interrupt_handler uart_rx_isr:12
void uart_rx_isr(void)
{rx_data=UDR;  LEDBuf[0]=rx_data;             //读接收缓冲器
}

基于Atmega16的串口通信实验相关推荐

  1. 基于FPGA Uart串口通信实验

    基于FPGA Uart串口通信实验 首先需要了解uart串口通信协议,根据个人专业需求不同,了解的层面可以不同. UART简介 通用异步收发传输器(Universal Asynchronous Rec ...

  2. 基于 MDK5的串口通信实验

    这里写目录标题 一.串口协议 二.STM32的USART串口通讯 1.新建工程 2.重定向printf函数 3.主要代码 4.编译生成.hex文件 5.烧录程序 6.串口工具运行结果 三.小结 一.串 ...

  3. 基于FPGA的UART串口通信实验(VHDL语言实现)

    一.前言: 最近在做UART串口通信的相关实验时,在网上查了很多资料,发现网上的大部分文章只注重理论,不注重代码,很多代码有错误不说,而且难以理解.故在完成此实验后,起了写一篇博客的心思,以供有想做相 ...

  4. 【正点原子FPGA连载】第十四章 串口通信实验 -摘自【正点原子】新起点之FPGA开发指南_V2.1

    1)实验平台:正点原子新起点V2开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=609758951113 2)全套实验源码+手册+视频下载地址:ht ...

  5. 27.串口通信实验源码讲解

    串口通信实验源码讲解 笔记基于正点原子官方视频 视频连接https://www.bilibili.com/video/BV1Wx411d7wT?p=71&spm_id_from=333.100 ...

  6. android 平板串口调试,实验六:FSPAD_702平板串口通信实验

    [实验内容] 基于FSPAD_702平板,实现串口通信. [实验目的] 熟悉FSPAD_702平板串口通信的整体流程. [实验环境] Ubuntu 10.04虚拟机,FSPAD_702开源平板,usb ...

  7. 树莓派4bpython串口通信解读数据_树莓派基础实验36:通用串口通信实验

    一.介绍 对于树莓派 3B+来说,他的UART功能有三种: 1.内部蓝牙使用: 2.控制终端使用: 3.与其他设备进行串口通信. 在树莓派基础实验35:USB TO TTL模块实验中学习了通过串口对树 ...

  8. windows通信端口初始化失败_STM32实例——USART串口通信实验(二)

    USART 串口通信配置步骤 在上面的介绍中,可能有的朋友很不理解,不过没有关系,下面我们讲解如何使用库函数对 USART 进行配置.这个也是在编写程序中必须要了解的.具体步骤如下:(USART 相关 ...

  9. 【正点原子FPGA连载】 第十七章 RS485串口通信实验 -摘自【正点原子】领航者ZYNQ之FPGA开发指南_V2.0

    1)实验平台:正点原子领航者ZYNQ开发板 2)平台购买地址:https://item.taobao.com/item.htm?&id=606160108761 3)全套实验源码+手册+视频下 ...

最新文章

  1. 基于OpenCV的条形码区域分割
  2. 深入了解volatile
  3. select元素的各种jquery修改获取添加方法
  4. java 复制一个数组_浅谈Java中复制数组的方式
  5. WinForm编程数据视图之DataGridView浅析
  6. Linux下高性能网络编程中的几个TCP/IP选项_SO_REUSEADDR、SO_RECVBUF、SO_SNDBUF、SO_KEEPALIVE、SO_LINGER、TCP_CORK、TCP_NODE
  7. 量子计算机的核心元件简称,计算机文化基础复习题(含答案).doc
  8. [GCC for C]编译选项---IDE掩盖下的天空
  9. [水动力学] 水动力学期末复习
  10. python中factor函数_Python入门-函数
  11. Python实战从入门到精通第四讲——数据结构与算法2之实现一个优先级队列
  12. 数据可视化—如何利用”奶牛“,把图组合起来
  13. IntelliJ IDEA for mac汉化
  14. oracle hcm cloud价格,Oracle HCM
  15. 文件或目录损坏且无法读取怎么办?数据恢复用这招
  16. Windows下挂载MSR分区
  17. rtklib-单点定位(pntpos.c)代码关键问题解析-satposs部分
  18. Ubuntu18.04启动后键盘和鼠标失灵
  19. 生产安全事故应急预案
  20. 关于如何快速学好,学懂Linux内核。内含学习路线

热门文章

  1. Python基础(三)列表、元组、字典、集合
  2. Html5 未掌握的知识笔记(随工作情况更新)
  3. 第1讲 1、层次分析法思想讲解
  4. 使用Reveal查看任意App的技巧
  5. Windows SQL Server 2012 R2 安装Intel I217-V/I218-V网卡驱动(转)
  6. iSpring Suite教程:使用iSpring创建视频讲座只需简单6步(上)
  7. 3Dmax动画云渲染农场使用教程!来自渲染101动画渲染支持
  8. 【项目设计】基于HLW8110计量芯片的电量计设计
  9. (附源码)计算机毕业设计ssm城市道路智能停车管理系统
  10. Mars3D功能示例原生JS版下载运行