前面我介绍了HC18M003单片机的SPI外设。这次就用SPI外设做个测试,与传统测试不同的是,这次我准备用CMOS/TTL系列的集成块作为SPI从机进行测试。方法是以SCK作为时钟脉冲,以SDA作为数据输入,利用串并转换电路实现低速下数据串行输出,同时点亮LED的方式。这样测试,结果直观,可以直接观测。只要发送周期合适,绝对可准确观察传送结果。
一、能进行串并转换的集成块
在着手测试之前,先介绍下和串并转换有关的集成块:74HC164/74HC194/CD4014/CD4015/CD4021 ,这里需要说明一下哈,如果使用工作电压是5V,LS系列的也是可以使用的74LS164/74LS194。
74HC164:八位串行入/并行输出移位寄存器
CD4094:8位移位存储总线寄存器
1、74HC164:
是8位边沿触发的移位寄存器,串行输入,并行输出。
管脚功能:
要求CLK时钟脉宽20nS以上,时钟最高25MHz。工作模式:
该8位移位寄存器具有与门使能控制串口输入和一个异步复位输入的特点。使能控制输入端能控制不需要的输入数据信号使其为低电平。当复位信号为低电平时,不管其他信号为何状态,其输出均为低电平;复位信号为高电平时,寄存器从第一位开始在每个时钟信号的上升沿对输入数据依次移位存储。
2、CC4094
管脚排列:
工作模式:
1脚为锁存端,
2脚为串行数据输入端,
3脚为串行时钟端。
1脚为高电平时,8位并行输出口Q1~Q8在时钟的上升沿随串行输入而变化;
1脚为低电平时,输出锁定。利用锁存端可方便地进行片选和级联输出控制。
1脚为并行输出状态控制端,
15脚为低电平时,并行输出端处在高阻状态,在用CD4094作显示输出时,可使显示数码闪烁。
9脚QS、
10脚Q′S是串行数据输出端,用于级联。QS端在第9个串行时钟的上升沿开始输出,Q′S端在第9个串行时钟的下降沿开始输出。
当CD4094电源为5V时,输出电流大于3.2MA,灌电流为1 MA。串行时钟频率可达2.5MHZ。
事实上,还有其他类似的集成块可用。就不一一列举了。我手头只有74HC164可用,所以,就以74HC164作为测试用的配料,加以利用了。按照它们的各自工作方式,以及单片机SPI外设的工作特点,搭建以下电路:
本打算利用上SS信号的,但因为需要使用反相处理,所以就无视这个信号了。SCL直接作为74HC164的时钟信号,MOSI作为74HC164的一个数据输入端。MISO不使用,直接通过上拉,默认一直接高电平。
程序中按照每秒发送一次的速度,通过SPI外设发送周期减一的数据给74HC164,这样我们就应该能在74HC164上看到二进制加法产生的效果,利用LED亮灭的方式表现出来。因为这种接法,LED的亮/灭是对应于电平输出0/1,所以需要SPI周期发送减一的方式。以下节选部分处理代码:
void main() { unsigned char d=255; unsigned long ms=5; //gui_ms_cnt = &ms; /************************************系统初始化****************************************/ OSCCON= 0x04; //Fosc=32M Fcpu=4M(Fosc4分频 2T) /************************************IO初始化*****************************************/ //ANSELD= 0x30; //SPIMAP=0XAA时的IO配置信息 //TRISD= 0x20; //ANSELA= 0Xff; //TRISA= 0xff; ANSELB= 0Xff; TRISB= 0xff; //SPIMAP= 0xAA; //SS映射PA7 SCK映射PA3 MOSI映射PD5 MISO映射PD4 SPIMAP= 0xFC; //SS映射PB7 SCK映射PB6 MOSI映射PB4 MISO映射PB5 // 未设置INTMAP,结果MOSI映射到PORTB4, SCK映射到PORTB6, // INTMAP = 0x40; // B6:MISOMAP2 = 1测试加上INTMAP设置,是否还是《SS映射PB7 SCK映射PB6 MOSI映射PB4 MISO映射PB5》 /************************************SPI初始化*****************************************/ SPCTL_CPOL_L_DF; //时钟极性选择 时钟空闲时为低电平 SPCTL_CPHA_FIRST_DF; //时钟相位选择 第一沿采样 SPCTL_SPR_FCPU_4_DF; //SPI为CPU时钟4分频 SPCTL_SSIG_DIS_DF; //主从机由MSTR决定 SPCTL_MSTR_M_DF; //主从机选择 主机 SPCTL_DORD_M_DF; //模式选择位 MSB SPCTL_SPEN_EN_DF; //SPI使能 /****************定时器初始化:T0******************/ OPTION = 0X07; // 分频寄存器配置256分频 T0CS = 0; // T0 模式选择寄存器:定时器模式,计数时钟Fcpu,休眠和绿色模式下停止 T0OSCEN = 0; // 禁止定时器模块0使用计数时钟 T0SE = 0; // 定时器模式,计数时钟Fcpu /********************中断设置********************/ T0IE = 1; //打开T0中断 //SPIIE = 1; // 允许SPI中断 PEIE = 1; //允许未屏蔽中断 GIE = 1; //允许总中断 while(1) { SPDAT = d; //发送数据5A while(!SPIIF); //等待发送完成 d--; //gui_ms_cnt=50; //while (gui_ms_cnt); delay_ms(1000); } } /*************************************************************************************** * @说明 中断服务函数 * @参数 无 * @返回值 无 * @注 包含定时器0中断 ***************************************************************************************/ void interrupt all_isr(void) { GIE=0; // 定时器0中断 if(T0IF) { T0 = 0xF0; //T0定时时间1ms if (gui_ms_cnt>0) gui_ms_cnt--; T0IF = 0; //清除T0中断标志位 } GIE=1; }
二、芯片中设置SPI外设使用的IO口
前面发送资料中,没有说明端口映射的问题。对HC18M003一样有端口复用的问题,对TSSOP20封装的HC18M003芯片,如下图:
可以看到对于SPI外设,有以下选项:
1、MOSI
可用PORTB4、PORTC1
2、MISO
可用PORTC0、PORTD4、PORTB5
3、SCK
可用PORTB6、PORTC2
4、SS
可用PORTB7、PORTA7
而在和SPI有关的寄存器配置中
1、端口映射寄存器 INTMAP和端口通讯端口映射寄存器 SPIMAP
(1)INT 端口映射寄存器 INTMAP
注意B6将被用于SPI映射用
(2)端口通讯端口映射寄存器 SPIMAP
为了实现以下设置:
SS - PORTB7
SCK - PORTB6
MOSI - PORTB4
MISO - PORTB5
要进行如下设置:
SPIMAP = 11 11 11 00 = 0xFC
INTMAP = 01000000 = 0x40
附上接线图片及测试图片,只接入了4个LED。但已经能看出二进制加法的显示模式。
最后一个图片,是由MP4视频转换为gif的图片,清晰度下降,但可以看得清二进制的变化了。
以下是例程(包中有一些无用代码,没有专门整理,不影响阅读):