370 likes | 630 Views
第八章 AVR 串行接口及其应用. 1 、 UART 串行通信 2 、 SPI 总线接口 3 、 I2C 总线接口. UART 串口通信. 1 、串行通信概述 2 、 RS-232 总线接口 3 、硬件设计 4 、程序设计. 1 、串行通信概述. 单片机的数据通信有两种方式:并行通信和串行通信。并行通信指数据字节的各位同时发送或接收,而串行通信是指数据字节一位一位按顺序发送或接收。 并行通信传输线多,适用于短距离、跨速度的通信,计算机内部数据传输一般都是采用这种方法标准打印口是属并行端口。
E N D
第八章AVR串行接口及其应用 1、UART串行通信 2、SPI总线接口 3、I2C总线接口
UART串口通信 1、串行通信概述 2、RS-232总线接口 3、硬件设计 4、程序设计
1、串行通信概述 单片机的数据通信有两种方式:并行通信和串行通信。并行通信指数据字节的各位同时发送或接收,而串行通信是指数据字节一位一位按顺序发送或接收。 并行通信传输线多,适用于短距离、跨速度的通信,计算机内部数据传输一般都是采用这种方法标准打印口是属并行端口。 串行通信仅需单线传输信息,适用于长距离传输数据,由于每次传送一位,适用传送速度比较慢,串行口UART、鼠标口和USB口都是串行端口。
串口通信又分异步和同步两种方式,其中异步串行通信是最常用的方式。异步串行通信是指通信双方以一个字符作为数据传送单位且发送方传送字符的间隔时间不一定,而在同一个字节中的两个相邻为的时间间隔是固定的。同步串行通信是指允许连续发送一序列字符,而每个字符的数据位数都相同,且没有起始位和停止位,通信过程中每个字节的时间间隔是相等的,而且每个字节的为的时间间隔也是固定的。串口通信又分异步和同步两种方式,其中异步串行通信是最常用的方式。异步串行通信是指通信双方以一个字符作为数据传送单位且发送方传送字符的间隔时间不一定,而在同一个字节中的两个相邻为的时间间隔是固定的。同步串行通信是指允许连续发送一序列字符,而每个字符的数据位数都相同,且没有起始位和停止位,通信过程中每个字节的时间间隔是相等的,而且每个字节的为的时间间隔也是固定的。
2、RS-232总线接口 目前RS-232是应用最广泛的一种串行接口,最初由电子工业协会(EIA)于1962年制订并发布,命名为EIA-232-E。RS-232被定义为一种在低速率窜货通信中增加通信距离的单端标准,采取不平衡传输方式,即所谓单端通信。完成RS-232通信必须通过接口转换芯片,将TTL电平转换为上位机串口匹配的电平。常用的接口转换芯片有MAX232、MAX3232等。
下面以AMX232为例介绍。 MAXX232的主要性能如下: 1、5V单电源供电; 2、CMOS制造工艺; 3、两路接收器/发生器; 4、+-30V输入电平; 5、低的工作电流,典型值8mA; 6、符合TIA/EIA-232-E标准和ITUV2.8建议;
硬件设计 • 对于用户来说,使用RS232进行串口通信时,只需要关心器件的外围接线即可,而不必深入协议的电器细节。
程序设计及详情 • #include "uart.h"unsignedchar receive_data=0;#pragma interrupt_handler RX_ISR:12void RX_ISR(void) {unsignedchar comm_tempRec; comm_tempRec=UDR; receive_data= comm_tempRec;}
void uartSetBaudRate(unsignedlong baudrate){unsignedint baudratDiv; baudratDiv = (F_CPU/(baudrate*16L)-1); UBRRH=(unsignedchar)(baudratDiv>>8); UBRRL=(unsignedchar)baudratDiv;}
void uartInit(void) { UCSRA=0X00; //enable RxD/TxD and interrupts //UCSRB|=(1<<RXCIE)|(0<<TXCIE)|(1<<RXEN)|(1<<TXEN); UCSRB=0XD8; uartSetBaudRate(UART_DEFAULT_BAND_RATE); //UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0); UCSRC=0X86; UCSRB|=0X80; SEI(); }
void uartSendByte(unsignedchar txData){while(!(UCSRA&(1<<UDRE))); // send byte UDR=txData;}unsignedchar uartReceiveService(void){unsignedchar c; c=UDR; uartSendByte(c);return UDR;}
unsignedchar uart_receive( void ){unsignedchar c;while ( !(UCSRA & (1<<RXC)) ){//rst_wdog(); }c=UDR;//uartSendByte(c);return c;}
2、SPI总线接口 1、SPI总线接口概述 2、硬件设计 3、程序设计
1、SPI总线接口概述 SPI是美国摩托罗拉公司推出的一种同步串行传输规范,常作为单片机外设芯片串行扩展接口。SPI接口在CPU和外围低速器件之间进行同步串行数据传输,在主器件的移位脉冲下,数据按位传输,高位在前,低为在后,为全双工通信。数据传输速度总体来说比I2C总线要快,可达到几兆位每秒。
SPI有下面4个引脚: • SS:从器件选择线 • SDO:串行数据输出线 • SDI:串行数据输入线 • SCK:同步串行时钟线
SPI接口有如下特点: • 高速的全双工总线 • 3线同步数据传输 • 主/从机操作 • 7种可编程的比特率 • 传送中断结束,写碰撞标志检测,可以从闲置模式唤醒 • 作为主机时具有双速模式
3、硬件设计 • 通过SPI总线外接25VF016的电路,其中ATmega16的SPI接口中的MOSI、MISO、SCK分别与25FV016的引脚SI、SO、SCK相连。
4、程序设计及详解 功能:甲通过SPI总线向乙发送数据 说明:先进行SPI总线接口的设置,再发送数据 #include<avr/io.h> #define SS PB0 #define SCK PB1 #define MOSI PB2 #define MISO PB3 //SPI总线接口相关引脚初始化 Void SPI_init(void)
{ // MISO设置为输入,上拉电阻关闭,其它默认为1 PORTB |=_BV(SCK)|_BV(MOSI)|_BV(SS)|_BV(MISO); //SCK、MOSI和CS端口对应脚设置为输出 DDRB|=_BV(SCK)|_BV(MSTR)|_BV(SS); //SPI 中断禁止,SPI使能,master模式,MSB前,SPI模式3,SCK频率Fclk/4 SPCR=_BV(SPE)|_BV(MSTR)|_BV(CPHA)|_BV(SPR1)|_BV(SPR0); }
//SPI总线接口输出一字节数据 Uint8_t spi_write(uint8_t data) { SPDR=data; while(!(SPSR & _BV(SPIF))); return SPDR; } void main(void) { SPI_init(); //初始化甲的SPI spi_write(0xFF); //向乙发送数据0xFF }
功能:乙通过SPI总线和中断接收来自甲的数据 说明:先进行SPI总线接口的设置,再通过中断接收数据 #include<avr/io.h> #include<stdint.h> #define SS PB0 #define SCK PB1 #define MOSI PB2 #define MISO PB3 //定义保存接收到的数据的变量 uint8_t data; //SPI总线接口相关引脚初始化
void SPI_init(void) { // MISO设置为输入,上拉电阻关闭,其它默认为1 PORTB |=_BV(SCK)|_BV(MOSI)|_BV(SS)|_BV(MISO); //SCK、MOSI和CS端口对应脚设置为输出 DDRB|=_BV(SCK)|_BV(MSTR)|_BV(SS); //SPI 中断禁止,SPI使能,master模式,MSB前,SPI模式3,SCK频率Fclk/4 SPCR=_BV(SPE)|_BV(MSTR)|_BV(CPHA)|_BV(SPR1)|_B V(SPR0); } //开全局中断 sei(); }
//SPI总线读一字节数据 Void spi_read(void) { data=SPDR; } //SPI传输完成中断的中断服务程序 SIGNAL(SIG_SPI) { spi_read(void); }
Void main(void) { SPI_init(); //初始化甲的SPI While(1); //等待中断 }
I2C总线接口 1、I2C总线接口概述 2、与AT24C64接口 3.、硬件设计 4、程序设计
1、I2C总线接口概述 • I2C通信协议是菲利普公司发明的一种串行通信协议。所有的器件都可以通过两线——时钟线SCL和信号线SDA相连,SDA和SCL信号线都是双向线路,连接到总线的器件的输出级必须是开漏或开集电极的结构以实现“线与”功能。I2C 总线上的每一个器件都具有一个独立的7位地址,因而最多能支持128个器件。I2C总线的通信速率有标准的100Kbps及快速的400Kbps.
I2C总线最主要的优点是其简单性和有效性。它由简单的双向通信的两线接口组成,为集成电路之间提供有效的控制。一条线路用来传输时钟,另外一条用来传输数据。通过一个带有缓冲区的接口,数据可以被I2C发送或接收。控制和状态信息则通过一套内存映射寄存器来传送。I2C总线最主要的优点是其简单性和有效性。它由简单的双向通信的两线接口组成,为集成电路之间提供有效的控制。一条线路用来传输时钟,另外一条用来传输数据。通过一个带有缓冲区的接口,数据可以被I2C发送或接收。控制和状态信息则通过一套内存映射寄存器来传送。
2、与AT24C64接口 AT24C64是ATMEL公司的两线制串行E2PROM芯片。共有64KB字节的存储容量。具有结构紧凑、存储容量大等优点。芯片与单片机之间使用I2C接口通信,接口电路简单、操作方便,适合存储单片机系统中一些重要的数据。
在对AT24C64进行读、写操作之前,先设置开始状态。方法是:设置SCL保持高电平,在SDA总线上设置一个有高电平向低电平的跳变,即START信号。在通信结束时,需设置一个结束状态,即将SCL总线保持高电平,并在SDA总线上设置一个低电平向高电平的跳变。设置结束状态后,器件脱离通信状态。在对AT24C64进行读、写操作之前,先设置开始状态。方法是:设置SCL保持高电平,在SDA总线上设置一个有高电平向低电平的跳变,即START信号。在通信结束时,需设置一个结束状态,即将SCL总线保持高电平,并在SDA总线上设置一个低电平向高电平的跳变。设置结束状态后,器件脱离通信状态。
3.、硬件设计 • ATmega16与AT24C64的硬件连接图。图中AT24C64的地址A0~A2都设置为0,这样AT24C64的器件写地址为0xA0,器件读地址为0xA1。AT24C64的串行是在线SCL与PD0相连,串行数据线SDA与PD1相连。按照I2C协议的接线要求,对SDA线接上拉电阻,保证其数据传输的可靠性。
4、程序设计 #include <iom16v.h> #include <macros.h> //设定读写地址 #define WADD24C04 0xa0 //写字节命令及器件地址(根据地址实际情况改变), 1010 A2 A1 A0 0 #define RADD24C04 0xa1 //读命令字节及器件地址(根据地址实际情况改变), 1010 A2 A1 A0 1
函数名称: void Uart0Init(void) 函数功能: 串口初始化 void Uart0Init(void) { UCSRB = 0x00; //关串口 UCSRA = 0x02; //倍速模式 UCSRC = BIT(URSEL) | 0x06; //写UCSRC寄存器,设定8个bit UBRR = 12; //设定串口波特率为600 UCSRB = 0x98; //开串口 }
函数名称: void UartRecvData(void) 函数功能: 接收数据 #pragma interrupt_handler UartRecvData:12 void UartRecvData(void) { uchar temp1; temp1 = UDR; }
函数名称: void UartTransmitData(uchar *SendData, uchar len) 函数功能: 发送字符串 void UartTransmitData(uchar *SendData, uint len) { uint i; for( i = 0; i < len; i++) { while(!(UCSRA&0x20)); //判断数据寄存器是否为空 UDR = SendData[i]; } }
函数名称: void InitDevices(void) 函数功能: 初始化各种信息 void InitDevices(void) { CLI(); //关全部中断 Uart0Init(); SEI(); //开全中断 } void main(void) { /*第一次写程序*/ uchar temp[] = "123456789"; //上电初始化24C02中的数据, I2C_Write_(WADD24C02,0,temp,8); //断电后屏蔽初始化程序,打开下面的程序*/ uchar i,temp2[8];
uint j; j = 2000; InitDevices(); while(j --); { i = 167; while(i--); } I2C_Read_(WADD24C04,0x00,RADD24C04,temp2,8);
j = 2000; while(j --); { i = 167; while(i--); } while(1); UartTransmitData(temp2, 8); }