ATMEGA16的USART串口发送与接收数据示例程序

合集下载

基于ATmega16单片机的USART串口通信测试程序

基于ATmega16单片机的USART串口通信测试程序

基于ATmega16单片机的USART串口通信测试程序/************************************************************** *************** 编译环境:ICC AVR。

文件名:基于ATmega16单片机的USART串口通信测试程序功能:利用ATmega16的USART,从TXD异步串出数据,将TXD 与RXD短接,从RXD输入,通过PC口送到一个LED数码管显示,实现了自发自收的过程?作者:赵国朋班级:鹏程001时间:2013年04月5日修改:无备住:一.硬件接口电路描述1.晶振:8MHz2.MCU的PC口与共阴极数码管相接3.TXD与RXD相接TXD --- RXD/************************************************************** ***************/ #include //包含单片机型号头文件#include //包含"位操作"头文件#define uchar unsigned char //宏定义#define uint unsigned int#define ulong unsigned long#define BAUD 9600 //波特率采用9600b/s#define CRYSTAL 8000000 //系统时钟为8MHz//计算和定义波特率设置参数#define BAUD_SETTING (uint)((ulong)CRYSTAL/(16*(ulong)BAUD)-1)#define BAUD_H (uchar)(BAUD_SETTING>>8)#define BAUD_L (uchar)(BAUD_SETTING)//USART控制和状态寄存器的标志位定义#define FRAMING_ERROR (1<<fe)< bdsfid="122" p=""></fe)<>#define PARITY_ERROR (1<<pe)< bdsfid="124" p=""></pe)<>#define DATA_OVERRUN (1<<dor)< bdsfid="126" p=""></dor)<>#define DATA_REGISTER_EMPTY (1<<udre)< bdsfid="128" p=""></udre)<>#pragma interrupt_handler USART_Rx_Isr:12 //USART接收中断服务#pragma data:dataflash Duan_table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};// 显示段码值0~F /************ MCU初始化函数**************//************************************************************** **************** 函数名:MCU_Init()功能:MCU初始化参数:无返回值:无/************************************************************** **************** /void MCU_Init(){PORTC=0X00;DDRC=0XFF;PORTD=0X03;DDRD=0X02;}/************ USART初始化函数**************//************************************************************** **************** 函数名:USART_Init()功能:USART初始化参数:无返回值:无/************************************************************** **************** /void USART_Init(){// DDRD=0X02;//PORTD=0X03;UCSRA=0X00;UCSRB=(1<<rxcie)|(1<<rxen)|(1<<=""></rxcie)|(1<<rxen)|( 1<//UCSRB=0X98;UCSRC=(1<<ursel)|(1<<ucsz1)|(1<<="" bdsfid="161" p=""></ursel)|(1<<ucsz1)|(1<//UCSRC=0X86UBRRH=BAUD_H;UBRRL=BAUD_L;}/************ USART中断服务函数**************//************************************************************** **************** 函数名:USART_Rx_Isr()功能:USART中断服务,将欲显示的数码送到I/O寄存器参数:无返回值:无/************************************************************** **************** /void USART_Rx_Isr(){uchar status,data;//DDRC=0XFF;status=UCSRA;data=UDR;if((status&(FRAMING_ERROR|PARITY_ERROR|DATA_OVERRU N))==0)PORTC=Duan_table[data];}/************ USART发送数据函数**************//************************************************************** **************** 函数名:USART_Transmit()功能:将要发送的数据送到USART缓冲区UDR中参数:uchar data返回值:无/************************************************************** **************** /void USART_Transmit(uchar data)while(!(UCSRA&DATA_REGISTER_EMPTY));UDR=data;}/************ 延时函数**************//************************************************************** **************** 函数名:Delay_Us()、Delay_Ms()功能:微秒级、毫秒级延时参数:Us --- 欲延时的us数Ms --- 欲延时的ms数返回值:无/****************************************************************************** /void Delay_Us(uint Us){uint i;Us=Us*5/4; //5/4是在8MHz晶振下,通过软件仿真反复实验得到的数值for( i=0;i<us;i++);< bdsfid="203" p=""></us;i++);<>}void Delay_Ms(uint Ms){uint i,j;for( i=0;i<ms;i++)< bdsfid="209" p=""></ms;i++)<>for(j=0;j<1141;j++);//1141是在8MHz晶振下,通过软件仿真反复实验得到的数值}/************ 主函数**************//************************************************************** **************** 函数名:main()功能:参数:无返回值:无/************************************************************** **************** /void main()uchar i=0;//定义变量MCU_Init();USART_Init();SREG=BIT(7);//开全局中断while(1){for(i=0;i<16;i++) {USART_Transmit(i); Delay_Ms(500);}}}。

ATmega162双串口应用

ATmega162双串口应用
}
/*UART1初始化*/
void uart1_init(void)
{
UCSR1A = 0x00;
UCSR1B |= (1 << RXCIE1)|(1 << TXEN1)|(1 << RXEN1); //接收中断、发送接收使能
UCSR1C |= (1<<URSEL1)|(1 << UCSZ11)|(1 << UCSZ10); //8位数据位
UDR1 = i; //发送数据
}
#pragma interrupt_handler uart1_rx_isr:iv_USART1_RXC
void uart1_rx_isr(void) //UART1接收中断服务程序
{
uart1_transmit(UDR1); //将接收到的数据通过UART1发送
while(1)
{
;
}
}
/************************************
编译环境:ICC-AVR
芯片型号:ATmega162
时钟频率:11.0592MHz
函数功能:将ATmega162双串口串联起来,
通过PC串口向单片机发送数据,
单片机接收数据后再送回PC机
PORTB = 0x00;
}
/*UART0初始化*/
void uart0_init(void)
{
UCSR0A = 0x00;
UCSR0B |= (1 << RXCIE0)|(1 << TXEN0)|(1 << RXEN0); //接收中断、发送接收使能

ATMEGA16单片机与MCGS通信(MODBUS-RTU协议)

ATMEGA16单片机与MCGS通信(MODBUS-RTU协议)

#include <avr/io.h>#include <avr/interrupt.h>#include <util/delay.h>#include "ds18b20.h"#define uchar unsigned char#define uint unsigned intvolatile uchar reve_data,renum=0,mend=0,nend=0,a1=1,a2=1,a3=1,a4=1,a5=1,a6=1,a7=1,a8=1,a9=1; void INT_Init();#define BAUD 38400 //波特率38.4kbp/svolatile uchar rx[7]={0x01,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00};uchar tx[30];volatile uchar crcl=0x00,crch=0x00;uchar led=0xff;//发送字符void send_char( uchar data ){/* 等待发送缓冲器为空 */while ( !( UCSRA & (1<<UDRE)) );/* 将数据放入缓冲器,发送数据 */UDR = data;}void inti_port(){DDRB=0xff;PORTB=0xff;DDRC=0xff;PORTC=0x00;}//CRC效验,将结果存储到CRCok变量中。

checkcrc(uchar *q,uchar nend){uint wcrc=0xffff;int j=0,i=0;for(i=0;i<nend;i++){wcrc ^= *q++;for(j=0;j<8;j++){if(wcrc&1){wcrc>>=1;wcrc ^= 0xa001;}else{wcrc>>=1;}}}crcl = wcrc;crch = wcrc>>8;}int main(void){inti_uart();inti_port();INT_Init();sei();while(1){gettemp();_delay_ms(1050);}}SIGNAL(SIG_UART_RECV){rx[renum++]=UDR;if(renum==8){renum=0;switch(rx[1]){case 0x01:if(!rx[3]){tx[0]=rx[0];//leD灯tx[1]=rx[1];tx[2]=0x01;DDRB=0X00;tx[3]=PORTB;DDRB=0XFF;checkcrc(tx,4);tx[4]=crcl;tx[5]=crch;send_string(tx,6);break;}else{tx[0]=rx[0];//继电器和蜂鸣器tx[1]=rx[1];tx[2]=0x01;DDRC=0X00;tx[3]=PORTC;tx[3]>>=7;DDRC=0XFF;checkcrc(tx,4);tx[4]=crcl;tx[5]=crch;send_string(tx,6);break;}case 0x04:tx[0]=rx[0];tx[1]=rx[1];tx[2]=rx[5]<<1;tx[3]=0x00;tx[4]=teml;tx[5]=0x00;tx[6]=temh;checkcrc(tx,nend=tx[2]+3);tx[tx[2]+3]=crcl;tx[tx[2]+4]=crch;send_string(tx,mend=tx[2]+5);break;case 0x05:DDRB=0XFF;switch(rx[3]){case 0x00:if(!rx[4])PORTB &= ~(1<<PB0);elsePORTB |= (1<<PB0);break;case 0x01:if(!rx[4])PORTB &= ~(1<<PB1);elsePORTB |= (1<<PB1);break;case 0x02:if(!rx[4])PORTB &= ~(1<<PB2);elsePORTB |= (1<<PB2);break;case 0x03:if(!rx[4])PORTB &= ~(1<<PB3);elsePORTB |= (1<<PB3);break;case 0x04:if(!rx[4])PORTB &= ~(1<<PB4);elsePORTB |= (1<<PB4);break;case 0x05:if(!rx[4])PORTB &= ~(1<<PB5);elsePORTB |= (1<<PB5);break;case 0x06:if(!rx[4])PORTB &= ~(1<<PB6);elsePORTB |= (1<<PB6);break;case 0x07:if(!rx[4])PORTB &= ~(1<<PB7);elsePORTB |= (1<<PB7);break;case 0x08:if(rx[4])PORTC |= (1<<PC7);elsePORTC &= ~(1<<PC7);break;}send_string(rx,8);break;default : break;}}}//*****************************红外线接收**********************************************////外部中断初始化void INT_Init(void){MCUCR |= _BV(ISC01); //选择外部中断0,下降沿触发中断MCUCR &= ~_BV(ISC00); //10:INT0的下降沿产生异步中断请求GICR |= (1 << INT0); //使能外部中断请求0DDRD &= ~_BV(PD2); //设置为输入,PORTD |= _BV(PD2); //使能上拉电阻}SIGNAL(SIG_INTERRUPT0){cli();uchar i,j,k = 0,addr[4] = {0};renum=0;GICR &= ~(1 << INT0); //禁止外部中断INT0 关闭外部中断,开始接受数据 for(i = 0;i < 14;i++){_delay_us(400);if(PIND & (1 << PD2)) //9MS内有高电平,则判断为干扰,退出处理程序 {GICR |= (1 << INT0); //使能外部中断INT0return;}}while(!(PIND & (1 << PD2))); //等待9ms低电平过去for(i = 0;i < 4;i++) //{for(j = 0;j < 8;j++)//{while(PIND & (1 << PD2)); //等待4.5ms高电平过去while(!(PIND & (1 << PD2))); //等待变高电平while(PIND & (1 << PD2))//计算高电平时间{_delay_us(100);k++;if(k >= 30) //高电平时间过长,则退出处理程序{GICR |= (1 << INT0); //使能外部中断INT0return; //}}addr[i] = addr[i] >> 1; //接受一位数据if(k >= 8){addr[i] = addr[i] | 0x80; //高电平时间大于0.56,则为数据1 }k = 0; //计时清零}}switch(addr[3]){DDRB=0XFF;case 0x07: if(a1){PORTB &= ~(1<<PB0);a1=0;}else{PORTB |= (1<<PB0);a1=1;}break;//1case 0x0b: if(a2){PORTB &= ~(1<<PB1);a2=0;}else{PORTB |= (1<<PB1);a2=1;}break;//2case 0x0f: if(a3){PORTB &= ~(1<<PB2);a3=0;}else{PORTB |= (1<<PB2);a3=1;}break;//3case 0x13: if(a4){PORTB &= ~(1<<PB3);a4=0;}else{PORTB |= (1<<PB3);a4=1;}break;//4case 0x17: if(a5){PORTB &= ~(1<<PB4);a5=0;}else{PORTB |= (1<<PB4);a5=1;}break;//5case 0x1b: if(a6){PORTB &= ~(1<<PB5);a6=0;}else{PORTB |= (1<<PB5);a6=1;}break;//6case 0x1f: if(a7){PORTB &= ~(1<<PB6);a7=0;}else{PORTB |= (1<<PB6);a7=1;}break;//7case 0x23: if(a8){PORTB &= ~(1<<PB7);a8=0;}else{PORTB |= (1<<PB7);a8=1;}break;//8case 0x03: if(a9)//蜂鸣器和继电器{PORTC |= (1<<PC7);a9=0;}else{PORTC &= ~(1<<PC7);a9=1;}break;//8case 0x27: PORTB=0X00;break;//9case 0x2b: PORTB=0XFF;break;//空格*/ default : break;}GICR |= (1 << INT0); //使能外部中断INT0sei();}#ifndef __ds18b20__H#define __ds18b20__H#include <avr/io.h>#include <util/delay.h>#include <avr/interrupt.h>#define uchar unsigned char#define uint unsigned int#define CLR_DIR_1WIRE DDRC &= ~(1<<PC6)//不再变化#define SET_DIR_1WIRE DDRC |= (1<<PC6) //IO改为输入口,高阻态,外部上拉电阻拉高#define SET_OP_1WIRE PORTC|= (1<<PC6) //改为输出口,输出低电平#define CLR_OP_1WIRE PORTC &=~(1<<PC6)#define CHECK_IP_1WIRE ( PINC & 0x40)void init_1820(void);void write_1820(unsigned char x);unsigned char read_1820(void);void gettemp(void);volatile uint Temperature;volatile unsigned char temh,teml;volatile uchar Num[4];void init_1820(void){SET_DIR_1WIRE; //设置PA0 为输出 SET_OP_1WIRE; //输出1CLR_OP_1WIRE; //输出0_delay_us(480); //480us以上SET_OP_1WIRE; //输出1CLR_DIR_1WIRE; //设置PA0 为输入 _delay_us(20); //15~60uswhile(CHECK_IP_1WIRE);SET_DIR_1WIRE;SET_OP_1WIRE;_delay_us(140); //60~240ussei();}void write_1820(unsigned char x){unsigned char m;for(m=0;m<8;m++){CLR_OP_1WIRE;if(x&(1<<m)) //写数据了,先写低位的! SET_OP_1WIRE;else{CLR_OP_1WIRE;}_delay_us(40); //15~60usSET_OP_1WIRE;}SET_OP_1WIRE;}unsigned char read_1820(void){unsigned char temp,k,n;temp=0;for(n=0;n<8;n++){CLR_OP_1WIRE;SET_OP_1WIRE;CLR_DIR_1WIRE;k=(CHECK_IP_1WIRE); //读数据,从低位开始 if(k)temp|=(1<<n);elsetemp&=~(1<<n);_delay_us(50); //60~120usSET_DIR_1WIRE;}return (temp);}void gettemp(void) //读取温度值{cli();init_1820(); //复位18b20write_1820(0xcc); // 发出转换命令write_1820(0x44);//_delay_ms(10); //不延时也好使,不知道怎么回事! init_1820();write_1820(0xcc); //发出读命令write_1820(0xbe);teml=read_1820(); //读数据temh=read_1820();sei();}#endif。

ATMEGA16的USART串口发送与接收数据示例程序

ATMEGA16的USART串口发送与接收数据示例程序

//ATMEGA16的USART串口发送与接收数据示例程序,采取中断的方式//发送200个FF,接收数据显示在数码管上,接收数据格式如09//编译环境 ICCAVR//系统时钟7.3728MHZ,设置熔丝位为外部高频石英晶体振荡,启动时间4.1ms//作者:David//日期:2013.10.20//*********************************************************************** // 包含文件//***********************************************************************#include <iom16v.h>#include <macros.h>#include <string.h>#include <stdio.h>#include <signal.h> //中断信号头文件//*********************************************************************** // 定义变量区//*********************************************************************** #define CH451_RESET 0x0201 //复位#define CH451_LEFTMOV 0x0300 //设置移动方式-左移#define CH451_LEFTCYC 0x0301 //设置移动方式-左循#define CH451_RIGHTMOV 0x0302 //设置移动方式-右移#define CH451_RIGHTCYC 0x0303 //设置移动方式-右循#define CH451_SYSOFF 0x0400 //关显示、键盘、看门狗#define CH451_SYSON1 0x0401 //开显示#define CH451_SYSON2 0x0403 //开显示、键盘#define CH451_SYSON3 0x0407 //开显示、键盘、看门狗功能#define CH451_DSP 0x0500 //设置默认显示方式#define CH451_BCD 0x058f //设置BCD译码方式#define CH451_TWINKLE 0x0600 //设置闪烁控制#define CH451_DIG0 0x0800 //数码管位0显示#define CH451_DIG1 0x0900 //数码管位1显示#define CH451_DIG2 0x0a00 //数码管位2显示#define CH451_DIG3 0x0b00 //数码管位3显示#define CH451_DIG4 0x0c00 //数码管位4显示#define CH451_DIG5 0x0d00 //数码管位5显示#define CH451_DIG6 0x0e00 //数码管位6显示#define CH451_DIG7 0x0f00 //数码管位7显示#define l ed0 0x0000 //数码管位0显示的数据0#define l ed1 0x0001 //数码管位0显示的数据1#define l ed2 0x0002 //数码管位0显示的数据2#define l ed3 0x0003 //数码管位0显示的数据3#define l ed4 0x0004 //数码管位0显示的数据4#define l ed5 0x0005 //数码管位0显示的数据5#define l ed6 0x0006 //数码管位0显示的数据6#define l ed7 0x0007 //数码管位0显示的数据7#define l edno 0x0010 //数码管灭#define dclk0 PORTD &= ~(1 << PD6) //串行数据时钟,上升延激活#define dclk1 PORTD |= (1 << PD6)#define din0 PORTD &= ~(1 << PD5) //串行数据输出,接CH451的数据输入#define din1 PORTD |= (1 << PD5)#define load0 PORTD &= ~(1 << PD4) //串行命令加载,上升延激活#define load1 PORTD |= (1 << PD4)#define uchar unsigned char#define uint unsigned int#define ulong unsigned long#define fosc 7372800 //晶振频率#define baud 9600 //设置波特率的大小uint tx_count=200,tx_flag=0xff;uchar A1,A2,A3;uchar usart_tx_data;uchar usart_rx_data;uchar table[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06, //显示用数据0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};//*************************************************************************// 初始化子程序//*************************************************************************void system_init(){PORTD=0x7F; //PD0设置为输入,PD1输出DDRD=0x72; //上拉电阻使能有效}void ch451_init() //先低后高,选择4线输入{din0;din1;}void usart_init(){UCSRB = 0x00;UCSRA=0x00; //单倍速模式UBRRL = (fosc/16/baud-1)%256; //写波特率的值UBRRH = (fosc/16/baud-1)/256;UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //UCSRC=086;写UCSRC寄存器 //异步通信无校验,8位数据1位停止位UCSRB=0xF8; //接收中断和发送中断允许}//***********************************************************************// 延时程序////***********************************************************************void delay_1ms(void){unsigned int i;for(i = 1; i < (unsigned int)(1144 - 2); i++);}void delay_ms(unsigned int n){unsigned int i = 0;while(i < n){delay_1ms();i++;}}//*************************************************************************// 数据处理函数//*************************************************************************void data_do(uchar temp_d){uchar A2t;A1=temp_d/100; //分出百,十,和个位A2t=temp_d%100;A2=A2t/10;A3=A2t%10;}//*************************************************************************// 串口相关中断服务子程序//************************************************************************* /* //数据发送结束中断向量#pragma interrupt_handler USART_TXC:14void USART_TXC() //中断服务程序{delay_ms(10); //相关操作}*///数据接收结束中断向量#pragma interrupt_handler USART_RXC:12void USART_RXC() //中断服务程序{CLI();//关中断usart_rx_data=UDR; //将接收到的数据取出data_do(usart_rx_data); //数据处理,得到个位十位百位SEI(); //开中断}/* //数据寄存器空中断向量#pragma interrupt_handler USART_UDRE:13void USART_UDRE() //中断服务程序{UDR=usart_tx_data; //发送数据到数据寄存器tx_count--;if(tx_count==0x00){tx_flag=0x01;}}*///************************************************************************* // 串口发送相关程序//************************************************************************* //发送单个字符void PutChar(char c){//PORTC |= (1 << PC3); //改变1487控制口为输出态,PC3=1 发送允许,接收禁止while(!(UCSRA & (1 << UDRE)));UDR = c;while(!(UCSRA&(1<<TXC)));UCSRA |= (1 <<TXC);//将发送结束标志位清零//PORTC &= ~(1 << PC3); //改变1487控制口为输出态,PC3=0 接收允许,发送禁止}//发送不带换行回车的字符串void PutNStr(unsigned char *Str){while (*Str != '\0'){PutChar(*Str);Str++;}}//发送带换行回车的字符串void PutStr(unsigned char *Str){while (*Str != '\0'){PutChar(*Str);Str++;}PutChar(0x0D);PutChar(0x0A);}//*************************************************************************// 输出命令子程序// 定义一无符号整型变量存储12字节的命令字//************************************************************************void ch451_write(unsigned int command){unsigned char i;load0; //命令开始for(i=0;i<12;i++){ //送入12位数据,低位在前if(command&1){din1;}elsedin0;dclk0;dclk1; //上升沿有效command>>=1;}load1; //加载数据}//*************************************************************************// 显示函数//*************************************************************************void display(uchar b_data,uchar s_data,uchar g_data){system_init();ch451_init();ch451_write(CH451_SYSOFF); //关显示、键盘、看门狗ch451_write(CH451_SYSON1); //开显示ch451_write(CH451_BCD); //设置BCD译码方式ch451_write(CH451_TWINKLE); //设置闪烁控制ch451_write(CH451_DIG0|table[b_data]); //显示接收到的值ch451_write(CH451_DIG1|table[s_data]);ch451_write(CH451_DIG2|table[g_data]);ch451_write(CH451_DIG3|ledno);ch451_write(CH451_DIG4|ledno);ch451_write(CH451_DIG5|ledno);ch451_write(CH451_DIG6|ledno);ch451_write(CH451_DIG7|ledno);}//*************************************************************************// 主程序//*************************************************************************void main(){system_init(); //系统初始化usart_init(); //usart串口初始化配置//usart_tx_data=0xff;SREG|=0x80; //开启全局中断while(1){/*while(tx_flag!=0x01) //数据发送是否完成,也可用发送完成中断 {//usart_tx_data=0xff;PutChar(0xFF);tx_count--;if(tx_count==0x00){tx_flag=0x01;}//delay_ms(10);}*///UCSRB=0xF0;display(A1,A2,A3); //显示接收到的数据 }}。

atmega16 UART同步模式接收PS2键盘扫描码

atmega16 UART同步模式接收PS2键盘扫描码

有关PS2键盘的大多是以中断方式接收扫描码,这样不停的中断,效率低,对于实验验证是可以的,UART的格式与PS2键盘的数据发送格式相同,这里提供atmge16使用USART 的同步模式,接收PS2键盘扫描码。

并在1602液晶上显示//LCD1602.h 头文件#include <util/delay.h>#define uint unsigned int#define En_H PORTD|=(1<<PD6)#define En_L PORTD&=~(1<<PD6)#define RW_R PORTD|=(1<<PD4)#define RW_W PORTD&=~(1<<PD4)#define RS_H PORTD|=(1<<PD5)#define RS_L PORTD&=~(1<<PD5)void Port_init(void){PORTA=0XFF;DDRA =0X00;PORTD=0XFF;DDRD =0X00;}void En_Toggle(void){En_H;_delay_us(20);En_L;_delay_us(20);}void Write_Command(uint8_t Command) { RW_W;RS_L;En_H;PORTA=Command;En_Toggle();}void Write_Data(uint8_t Data){RW_W;RS_H;En_H;PORTA=Data;En_Toggle();}void Write_Position(uint8_t row,uint8_t colum) {uint8_t p;if(row==0)p=0x80+colum;elsep=0xc0+colum;Write_Command(p);}void Write_String(char *s){for(;*s!='\0';s++)Write_Data(*s);}void Initialize_LCD(void){ DDRA=0xFF;DDRD|=(1<<PD5)|(1<<PD4)|(1<<PD6);_delay_ms(15);Write_Command(0x38);Write_Command(0x08);Write_Command(0x01);_delay_ms(5);Write_Command(0x04);_delay_ms(5);Write_Command(0x0c);}//UART同步模式接收PS2扫描码#include<avr/io.h>#include <avr/interrupt.h> #include <util/delay.h>#include"LCD1602.h"#define F_CPU 7372800ULconst char unshifted[36][2]= {{0x1c,'a'},{0x32,'b'},{0x21,'c'},{0x23,'d'},{0x24,'e'},{0x2B,'f'},{0x34,'g'},{0x33,'h'},{0x43,'i'},{0x42,'k'}, {0x4B,'l'}, {0x3A,'m'}, {0x31,'n'}, {0x44,'o'}, {0x4D,'p'}, {0x15,'q'}, {0x2D,'r'}, {0x1B,'s'}, {0x2C,'t'}, {0x3C,'u'}, {0x2A,'v'}, {0x1D,'w'}, {0x22,'x'}, {0x35,'y'}, {0x1A,'z'}, {0x45,'0'}, {0x16,'1'}, {0x1E,'2'}, {0x26,'3'}, {0x25,'4'},{0x36,'6'},{0x3D,'7'},{0x3E,'8'},{0x46,'9'},};const char shifted[36][2]= {{0x1c,'A'},{0x32,'B'},{0x21,'C'},{0x23,'D'},{0x24,'E'},{0x2B,'F'},{0x34,'G'},{0x33,'H'},{0x43,'I'},{0x3B,'J'},{0x42,'K'},{0x4B,'L'},{0x31,'N'},{0x44,'O'},{0x4D,'P'},{0x15,'Q'}, // {0x2D,'R'},{0x1B,'S'}, // {0x2C,'T'},{0x3C,'U'},{0x2A,'V'},{0x1D,'W'}, // {0x22,'X'},{0x35,'Y'},{0x1A,'Z'},{0x45,'0'},{0x16,'1'},{0x1E,'2'},{0x26,'3'},{0x25,'4'},{0x2E,'5'},{0x36,'6'},{0x3D,'7'},{0x46,'9'},};int data;int up,shift;SIGNAL(SIG_USART_RECV) //接收{int i;data=UDR;if (!up) //已接收的11位数据是通码(up为0) {switch (data)//开始翻译扫描码{case 0x13: up=1; break;case 0x12: shift=1; break;case 0x59: shift=1; break;default:if(!shift){for(i=0;i<36;i++)if(unshifted[i][0]==data){data=unshifted[i][1];break;}}else{for(i=0;i<36;i++)if(shifted[i][0]==data){data=shifted[i][1];break;}}}}else{up = 0;switch (data) //检测shift键释放 {case 0x12 : shift = 0;break; case 0x59 : shift = 0;break; default:break;}}void LCDplay(int data){Write_Position(0,0);Write_Data(data);}void LCD_set(void){Port_init();Initialize_LCD();Write_Command(0x01);_delay_ms(5);}int main(){DDRB&=~(1<<PD0);PORTD&=~(1<<PD0);DDRD&=~(1<<PD0);LCD_set();UCSRB=(1<<RXCIE)|(1<<RXEN); // 接收使能发送使能接受中断使能UCSRC=(1<<URSEL)|(1<<UMSEL)|(1<<UPM1)|(1<<UPM0)|(1< <UCPOL);sei();while(1){LCDplay(data);}}。

ATmega16串口程序-值得参考

ATmega16串口程序-值得参考

// USART Transmitter buffer
#define TX_BUFFER_SIZE 16
volatile char tx_buffer[TX_BUFFER_SIZE];
volatile unsigned char tx_wr_index,tx_rd_index,tx_counter;
if (++rx_wr_index == RX_BUFFER_SIZE) //写指针指向下一个单元,并判断是否到了队列的尾部,(不表示接受缓冲区是否满!)
rx_wr_index=0; //到了尾部,则指向头部(构成环状)
if (++rx_counter == RX_BUFFER_SIZE) //队列中收到字符加1,并判断是否队列已满
{
rx_counter=0; // 队列满了,队列中收到字符个数为0,表示队列中所有以前的数据作废,因为最后的数据已经把最前边的数据覆盖了
rx_buffer_overflow=1; //置缓冲区溢出标志。在主程序中必要的地方需要判断该标志,以证明读到数据的完整性
put_s("Hello!");
put_s("这是一个简单的高速的串口驱动程序");
put_s("请你输入任意的字符,单片机将返回你输入的字符");
while (1)
{
put_c(get_c());
}
}
//Makefile,主要的几项,只是针对我这里的程序,要灵活运用哦
//usart.h
//常量定义
#define BAUDRATE 9600 //波特率
//#define F_CPU 4000000 //晶振频率4.0MHz

ATMEGA16_串口接收程序

ATMEGA16_串口接收程序
UCSRB|=(1<<RXCIE)|(1<<RXEN)|(1<<TXEN);//接收结束中断使能,接收使能,发送使能
SREG=0X80;//打开全局中断
}
/****************************************************
发送数据函数
****************************************************/
写数据函数规定写数据的流程
*******************************************/
void write_data(uchar data) //data
{
uchar start_data,Hdata,Ldata;
start_data=0xfa; //写数据
Hdata=data&0xf0; //取高四位
Ldata=(data<<4)&0xf0; //取低四位
sendbyte(start_data);//发送起始信号
delay_us(1);
sendbyte(Hdata);//发送高四位
delay_us(1);
sendbyte(Ldata);//发送低四位
delay_us(1);
}
/**********************************************
LCD初始化函数
************************************************/
void LCD_init()
{
write_com(0x01);
delay(5) ; //清屏指令

基于AVR单片机--Atmega16的串口通信使用

基于AVR单片机--Atmega16的串口通信使用

基于AVR单片机--Atmega16的串口通信使用//以下程序经验正可以用,MCU:M16,晶振:8M,直接用USB转串口线上的公头(针头),//第2针(RXD)接M16上的PD1口(15脚TXD),第3针(TXD)接M16上的PD0口(14脚RXD),//第5针接地,此时若板上有MAX232,则需把MAX232芯片去掉,这样才能正常工作#include<avr/io.h>#include<avr/interrupt.h>#define uchar unsigned char#define uint unsigned int#define fosc 8000000//晶振频率#define BAUD 9600 //波特率void USART_send(uchar date)//发送一个字节{while(!(UCSRA&(1<<UDRE)));//等待USART数据寄存器为空,UDRE为1说明缓冲器为空,已准备好进行数据接收或发送UDR=date;//发送数据}void init(){DDRB=0xff;//设置PB口为输出PORTB&=~(_BV(PB4)|_BV(PB5)|_BV(PB6)|_BV(PB7));//让高4位的LED灭//波特率寄存器设置UBRRH=(fosc/BAUD/16-1)/256;UBRRL=(fosc/BAUD/16-1)%256;//UCSRB|=_BV(RXEN)|_BV(TXEN)|_BV(RXCIE);UCSRB|=(1<<RXEN)|(1<<TXEN)|(1<<RXCIE);//使能发送,接收,接收完成中断sei();//开全局中断}int main(){init();USART_send('d');//发送数据'd'while(1);}volatile char date1;SIGNAL(SIG_UART_RECV){date1=UDR;//接收数据PORTB=date1;}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

//ATMEGA16的USART串口发送与接收数据示例程序,采取中断的方式//发送200个FF,接收数据显示在数码管上,接收数据格式如09//编译环境 ICCAVR//系统时钟7.3728MHZ,设置熔丝位为外部高频石英晶体振荡,启动时间4.1ms//作者:David//日期:2013.10.20//*********************************************************************** // 包含文件//***********************************************************************#include <iom16v.h>#include <macros.h>#include <string.h>#include <stdio.h>#include <signal.h> //中断信号头文件//*********************************************************************** // 定义变量区//*********************************************************************** #define CH451_RESET 0x0201 //复位#define CH451_LEFTMOV 0x0300 //设置移动方式-左移#define CH451_LEFTCYC 0x0301 //设置移动方式-左循#define CH451_RIGHTMOV 0x0302 //设置移动方式-右移#define CH451_RIGHTCYC 0x0303 //设置移动方式-右循#define CH451_SYSOFF 0x0400 //关显示、键盘、看门狗#define CH451_SYSON1 0x0401 //开显示#define CH451_SYSON2 0x0403 //开显示、键盘#define CH451_SYSON3 0x0407 //开显示、键盘、看门狗功能#define CH451_DSP 0x0500 //设置默认显示方式#define CH451_BCD 0x058f //设置BCD译码方式#define CH451_TWINKLE 0x0600 //设置闪烁控制#define CH451_DIG0 0x0800 //数码管位0显示#define CH451_DIG1 0x0900 //数码管位1显示#define CH451_DIG2 0x0a00 //数码管位2显示#define CH451_DIG3 0x0b00 //数码管位3显示#define CH451_DIG4 0x0c00 //数码管位4显示#define CH451_DIG5 0x0d00 //数码管位5显示#define CH451_DIG6 0x0e00 //数码管位6显示#define CH451_DIG7 0x0f00 //数码管位7显示#define l ed0 0x0000 //数码管位0显示的数据0#define l ed1 0x0001 //数码管位0显示的数据1#define l ed2 0x0002 //数码管位0显示的数据2#define l ed3 0x0003 //数码管位0显示的数据3#define l ed4 0x0004 //数码管位0显示的数据4#define l ed5 0x0005 //数码管位0显示的数据5#define l ed6 0x0006 //数码管位0显示的数据6#define l ed7 0x0007 //数码管位0显示的数据7#define l edno 0x0010 //数码管灭#define dclk0 PORTD &= ~(1 << PD6) //串行数据时钟,上升延激活#define dclk1 PORTD |= (1 << PD6)#define din0 PORTD &= ~(1 << PD5) //串行数据输出,接CH451的数据输入#define din1 PORTD |= (1 << PD5)#define load0 PORTD &= ~(1 << PD4) //串行命令加载,上升延激活#define load1 PORTD |= (1 << PD4)#define uchar unsigned char#define uint unsigned int#define ulong unsigned long#define fosc 7372800 //晶振频率#define baud 9600 //设置波特率的大小uint tx_count=200,tx_flag=0xff;uchar A1,A2,A3;uchar usart_tx_data;uchar usart_rx_data;uchar table[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06, //显示用数据0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};//*************************************************************************// 初始化子程序//*************************************************************************void system_init(){PORTD=0x7F; //PD0设置为输入,PD1输出DDRD=0x72; //上拉电阻使能有效}void ch451_init() //先低后高,选择4线输入{din0;din1;}void usart_init(){UCSRB = 0x00;UCSRA=0x00; //单倍速模式UBRRL = (fosc/16/baud-1)%256; //写波特率的值UBRRH = (fosc/16/baud-1)/256;UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //UCSRC=086;写UCSRC寄存器 //异步通信无校验,8位数据1位停止位UCSRB=0xF8; //接收中断和发送中断允许}//***********************************************************************// 延时程序////***********************************************************************void delay_1ms(void){unsigned int i;for(i = 1; i < (unsigned int)(1144 - 2); i++);}void delay_ms(unsigned int n){unsigned int i = 0;while(i < n){delay_1ms();i++;}}//*************************************************************************// 数据处理函数//*************************************************************************void data_do(uchar temp_d){uchar A2t;A1=temp_d/100; //分出百,十,和个位A2t=temp_d%100;A2=A2t/10;A3=A2t%10;}//*************************************************************************// 串口相关中断服务子程序//************************************************************************* /* //数据发送结束中断向量#pragma interrupt_handler USART_TXC:14void USART_TXC() //中断服务程序{delay_ms(10); //相关操作}*///数据接收结束中断向量#pragma interrupt_handler USART_RXC:12void USART_RXC() //中断服务程序{CLI();//关中断usart_rx_data=UDR; //将接收到的数据取出data_do(usart_rx_data); //数据处理,得到个位十位百位SEI(); //开中断}/* //数据寄存器空中断向量#pragma interrupt_handler USART_UDRE:13void USART_UDRE() //中断服务程序{UDR=usart_tx_data; //发送数据到数据寄存器tx_count--;if(tx_count==0x00){tx_flag=0x01;}}*///************************************************************************* // 串口发送相关程序//************************************************************************* //发送单个字符void PutChar(char c){//PORTC |= (1 << PC3); //改变1487控制口为输出态,PC3=1 发送允许,接收禁止while(!(UCSRA & (1 << UDRE)));UDR = c;while(!(UCSRA&(1<<TXC)));UCSRA |= (1 <<TXC);//将发送结束标志位清零//PORTC &= ~(1 << PC3); //改变1487控制口为输出态,PC3=0 接收允许,发送禁止}//发送不带换行回车的字符串void PutNStr(unsigned char *Str){while (*Str != '\0'){PutChar(*Str);Str++;}}//发送带换行回车的字符串void PutStr(unsigned char *Str){while (*Str != '\0'){PutChar(*Str);Str++;}PutChar(0x0D);PutChar(0x0A);}//*************************************************************************// 输出命令子程序// 定义一无符号整型变量存储12字节的命令字//************************************************************************void ch451_write(unsigned int command){unsigned char i;load0; //命令开始for(i=0;i<12;i++){ //送入12位数据,低位在前if(command&1){din1;}elsedin0;dclk0;dclk1; //上升沿有效command>>=1;}load1; //加载数据}//*************************************************************************// 显示函数//*************************************************************************void display(uchar b_data,uchar s_data,uchar g_data){system_init();ch451_init();ch451_write(CH451_SYSOFF); //关显示、键盘、看门狗ch451_write(CH451_SYSON1); //开显示ch451_write(CH451_BCD); //设置BCD译码方式ch451_write(CH451_TWINKLE); //设置闪烁控制ch451_write(CH451_DIG0|table[b_data]); //显示接收到的值ch451_write(CH451_DIG1|table[s_data]);ch451_write(CH451_DIG2|table[g_data]);ch451_write(CH451_DIG3|ledno);ch451_write(CH451_DIG4|ledno);ch451_write(CH451_DIG5|ledno);ch451_write(CH451_DIG6|ledno);ch451_write(CH451_DIG7|ledno);}//*************************************************************************// 主程序//*************************************************************************void main(){system_init(); //系统初始化usart_init(); //usart串口初始化配置//usart_tx_data=0xff;SREG|=0x80; //开启全局中断while(1){/*while(tx_flag!=0x01) //数据发送是否完成,也可用发送完成中断 {//usart_tx_data=0xff;PutChar(0xFF);tx_count--;if(tx_count==0x00){tx_flag=0x01;}//delay_ms(10);}*///UCSRB=0xF0;display(A1,A2,A3); //显示接收到的数据 }}。

相关文档
最新文档