机电传动控制 实验6数码管显示实验.docx
- 文档编号:24722220
- 上传时间:2023-05-31
- 格式:DOCX
- 页数:17
- 大小:579.67KB
机电传动控制 实验6数码管显示实验.docx
《机电传动控制 实验6数码管显示实验.docx》由会员分享,可在线阅读,更多相关《机电传动控制 实验6数码管显示实验.docx(17页珍藏版)》请在冰豆网上搜索。
机电传动控制实验6数码管显示实验
实验六数码管显示实验
1.实验目的
✧掌握串行移位寄存器工作原理;
✧理解串行时序;
✧掌握4位数码管显示数字的方法原理。
2.实验内容
✧在实验5的基础之上新建74HC595.c、74HC595.h、Displays.c、Displays.h实现串行移位寄存器驱动数码管显示数字的功能。
3.预备知识
✧串行移位数据寄存器相关概念;
✧共阳极数码管显示原理;
4.实验设备及工具
✧硬件:
PC机、STM32开发板、JLINK_V8仿真器;
✧软件:
KEILMDK4.12、JLINK_V8驱动。
5.实验原理及说明
✧74HC595简介:
74HC595是硅结构的CMOS器件,兼容低电压TTL电路,简单来说74HC595是一个8位串行数据转并行数据的一种元器件。
QA--QH:
八位并行输出端,可以直接控制数码管的8个段。
74hc595外形图
QH':
级联输出端。
将它接下一个595的SI端。
SI:
串行数据输入端。
✧74595的控制端说明:
1)/SCLR(10脚):
低电平时将移位寄存器的数据清零。
通常我将它接Vcc。
2)SCK(11脚):
上升沿时数据寄存器的数据移位。
QA-->QB-->QC-->...-->QH;下降沿移位寄存器数据不变。
(脉冲宽度:
5V时,大于几十纳秒就行了。
我通常都选微秒级);
3)RCK(12脚):
上升沿时移位寄存器的数据进入数据存储寄存器,下降沿时存储寄存器数据不变。
通常我将RCK置为低点平,当移位结束后,在RCK端产生一个正脉冲(5V时,大于几十纳秒就行了。
我通常都选微秒级),更新显示数据。
4)/G(13脚):
高电平时禁止输出(高阻态)。
如果单片机的引脚不紧张,用一个引脚控制它,可以方便地产生闪烁和熄灭效果。
比通过数据端移位控制要省时省力。
注意:
1)74164和74595功能相仿,都是8位串行输入转并行输出移位寄存器。
74164的驱动电流(25mA)比74595(35mA)的要小,14脚封装,体积也小一些。
2)74595的主要优点是具有数据存储寄存器,在移位的过程中,输出端的数据可以保持不变。
这在串行速度慢的场合很有用处,数码管没有闪烁感。
3)595是串入并出带有锁存功能移位寄存器,它的使用方法很简单,在正常使用时SCLR为高电平,G为低电平。
从SER每输入一位数据,串行输595是串入并出带有锁存功能移位寄存器,它的使用方法很简单,如下面的真值表,在正常使用时SCLR为高电平,G为低电平。
从SER每输入一位数据,串行输入时钟SCK上升沿有效一次,直到八位数据输入完毕,输出时钟上升沿有效一次,此时,输入的数据就被送到了输出端。
入时钟SCK上升沿有效一次,直到八位数据输入完毕,输出时钟上升沿有效一次,此时,输入的数据就被送到了输出端。
详细信息请参考74HC595数据手册。
✧共阳极数码管简介
共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管,共阳数码管在应用时应将公共极COM接到+5V,当某一字段发光二极管的阴极为低电平时,相应字段就点亮,当某一字段的阴极为高电平时,相应字段就不亮。
我们配套的STM32开发板板载4个0.36寸共阳极数码管,其原理图如下所示:
,其中3、8脚为COM公共端需要接入+5V电源,我们只要将对应的IO拉低对应的二极管就会亮起。
✧硬件设计
板载4位共阳极数码管驱动电路如下:
6.实验步骤
1)拷贝“实验5串口通信实验”工程文件并保存在..\STM32工程文件目录下并命名为“实验6数码管显示实验”,并修改对应的KEIL工程文件名称(实际步骤参考上节实验);
1)新建74HC595.c、74HC595.h、Displays.c、Displays.h,并保存在“实验6数码管显示实验”..\bsp目录下。
2)修改工程文件名称并打开工程文件
3)添加源文件到工程(相关操作参照实验1建立工程模板)
4)添加“74HC595.h”和”Displays.h”到“includes.h“文件
5)修改74HC595.c
#include"includes.h"
voidInit_74HC595(void)
{
RCC->APB2ENR|=1<<6;//使能PORTE时钟
/*初始化引脚控制位*/
GPIOE->CRL&=0xF0F00FFF;//PE3PE4PE6
/*将对应的控制引脚配置为推挽输出模式*/
GPIOE->CRL|=0x03033000;//PE3PE4PE6
}
从上面的一段代码前面的实验中我们已经讲了很多,在此我们不再赘述。
voidUpdate_74HC595(void)
{
Update_L;
delay_us(50);
Update_H;
delay_us(50);
}
Update_74HC595主要完成更新595输出的功能,根据数据手册的说明,我们需要使更新数据引脚产生一个上升沿,数据才能更新到输出,所以就有了上面的代码用于产生上升沿。
voidWrite_74HC595(u8*buf,u8data_len)
{
uint8_ti;
uint8_tj;
uint8_tData;//用于存放一个字节的数据
for(i=0;i { Data=buf[i]; for(j=0;j<8;j++) { Clk_L;//先将移位寄存器控制引脚置为低 delay_us(10); if(Data&0x80) { Data_H; } else { Data_L; } Data<<=1;//再将数据的次高位移到最高位 delay_us(10); Clk_H;//再置为高产生移位时钟上升沿,上升沿时数据寄存器的数据移位 } } Update_74HC595(); } 代码讲解: 这段代码的是操作74HC595的关键,每个595能够将8位串行数据转化为8位并行数据,即1个字节的数据,所以4个595级联的话发送给这一组595的数据就需要4个字节,更新一个595寄存器需要8个时钟脉冲,那么4个595数据就需要4*8=32个数据时钟脉冲,来一个脉冲那么595的移位寄存器里的数据就顺序的由低向高处移位即Q7->Q7’(链接下一片595的数据输入)、Q6->Q7….Q0->Q1、DS(当前595数据输入引脚数据)->Q0,实现595的数据迁移,根据数据手册,我们知道在时钟信号的上升沿时数据实现移位,所以就有了CLK拉低->确定数据信号(0或1)->CLK信号拉高->实现数据移位。 6)修改74HC595.h #ifndef__74HC595_H__ #define__74HC595_H__ /*数据宏定义*/ #defineData_HGPIOE->ODR|=1<<3 #defineData_LGPIOE->ODR&=~(1<<3)//PE3 #defineClk_HGPIOE->ODR|=1<<6 #defineClk_LGPIOE->ODR&=~(1<<6)//PE6 #defineUpdate_HGPIOE->ODR|=1<<4; #defineUpdate_LGPIOE->ODR&=~(1<<4)//PE4 voidInit_74HC595(void); voidWrite_74HC595(u8*buf,u8data_len); voidUpdate_74HC595(void); #endif 7)修改Displays.c #include"includes.h" uint8_tData_Buffer[4];//存储每个数码管所要显示的数据 uint8_tData_Code[11]={0xC0,0xF9,0xA4,0xB0,0X99,0X92,0X82,0XF8,0X80,0X90,0X7F};//0~9最后一个是数据“.”数据编码 说明: Data_Buffer数组我们用来存储4个74HC595所需要的数据,而下面的Data_Code则用来表示数字0~9以及“.”的数字编码。 例如我们要4个数码管显示9999,那么我们只需要将Data_Buffer[0]=Data_Buffer[1]=Data_Buffer[2]=Data_Buffer[3]=Data_Code[9],然后将这些数据写到595即可。 voidDisplays_Init(void) { Init_74HC595(); Write_74HC595(Data_Buffer,4); } 说明: 这段函数组要作用是初始化4个数码管,在上面这段代码中我们可以看到,我们主要做的就是初始化了其控制引脚而由于刚上电的时候Data_Buffer为0,所以初始化完成的结果便是4个数码管全部显示0000。 voidWrite_Displays(floatdata) { Config_Displays_Data(data); Drive_Displays(); } 说明: 函数voidWrite_Displays(floatdata)的作用顾名思义就是写数据到4个数码管,比方说我们要4个数码管显示1234,那么我们只需要调用Write_Displays(1234)即可,如果我们想要4个数码管显示5.99那么我们只需要调用Write_Displays(5.99)即可,这就是我们为什么将数据类型定义为”float”类型的目的,要实现上面所述的功能其关键在于如何配置4个595的数据,驱动数码管也就是驱动595而已,所以我们将目光转向Config_Displays_Data()函数即配置数据函数: voidConfig_Displays_Data(floatdata)//传进来的参数以及几位有效数 { uint8_tD0; uint8_tD1; uint8_tD2; uint8_tD3; floattemp; u16RE; temp=data; //最高显示9999 if(data>9999) { } else { //判断是否带小数 if(temp>(int)(data)) { //如果带有小数为简便起见默认数据有效位为两位,也就是说DS2的显示是必须要带上小数点的 //四位数码管数据显示格式为: xx.xx最大显示为99.99DS1显示十位、DS2显示个位,DS3、DS4显示小数 if(data>100) { //超出范围则不予显 } else { temp=temp*100; RE=(int)temp; D3=RE/1000;//取“千位”整数 D2=(RE%1000)/100;//取“百位”整数 D1=((RE%1000)%100)/10;//取“十位”整数 D0=(((RE%1000)%100)%10)/1;//取"个位"整数 Data_Buffer[0]=Data_Code[D0];//DS4 Data_Buffer[1]=Data_Code[D1];//DS3 Data_Buffer[2]=Data_Code[D2]&Data_Code[10];//DS2 Data_Buffer[3]=Data_Code[D3];//DS1 } } else//如果没有带有小数 { //取各个数据位的数据 D3=(int)(data)/1000;//取“千位”整数 D2=((int)data%1000)/100;//取“百位”整数 D1=(((int)data%1000)%100)/10;//取“十位”整数 D0=((((int)data%1000)%100)%10)/1;//取"个位"整数 Data_Buffer[0]=Data_Code[D0];//DS4 Data_Buffer[1]=Data_Code[D1];//DS3 Data_Buffer[2]=Data_Code[D2];//DS2 Data_Buffer[3]=Data_Code[D3];//DS1 } } } 说明: 此函数输入形参为”floatdata”即我们要显示的数据,由于我们板子只有4个数码管,所以我们最大只能显示9999,我们申请了4个u8类型的变量 D3-D0用来存储DS4-DS1四个数码管所要显示的数据,比如四个数码管DS1-DS4要显示1234,那么D3=4,D2=3,D3=1,D0=1,Data_Code[1]对应的数码管编码“1”以此类推;此外我们申请了一个float类型的temp变量,存储输入形参的数值,其作用主要是用来判断输入数据是整数还是小数,具体的用法,我们可以用下面的语句来进行判断 if(temp>(int)(data)) 首先我们将输入形参用(int)data强制转换为整形数,然后再与temp(保存输入形参的数值)进行比较,如果temp>(int)data,则说明传进来的参数为非整数,如果等于的话则说明输入的为整数,例如若data=6.34,temp=data=6.34,(int)data=6,那么temp>(int)data是成立的,由此判断出输入形参为非整数。 具体请看代码,在此不再详细描述,下面我们再讲讲下面的这段代码: D3=(int)(data)/1000;//取“千位”整数 D2=((int)data%1000)/100;//取“百位”整数 D1=(((int)data%1000)%100)/10;//取“十位”整数 D0=((((int)data%1000)%100)%10)/1;//取"个位"整数 在这我们需要注意的是取余取整的过程中,被操作数必须是整数,所以需要将float类型的数据进行int类型转化,此外我们还需要注意下面这段代码,如果我们想要某个数码管显示数字的同时显示”.”,那么我们就需要类似于下面的这段代码: Data_Buffer[2]=Data_Code[D2]&Data_Code[10];//DS2 下面这段代码就是简单的调用Write_74HC595()函数驱动595显示数据。 voidDrive_Displays(void) { Write_74HC595(Data_Buffer,4); } 8)修改Displays.h文件如下 #ifndef__DISPLAYS_H__ #define__DISPLAYS_H__ voidDisplays_Init(void); voidConfig_Displays_Data(floatdata); voidDrive_Displays(void); voidWrite_Displays(floatdata); #endif 9)修改voidApplication.c #include"includes.h" /* ------------------------------------------------------------------------ *函数名称: voidBoard_Init(void) *函数功能: 初始化开发板硬件 *输入形参: 无 *返回值: ------------------------------------------------------------------------ */ voidBoard_Init(void) { SystemInit(); //调用延时初始化函数,利用SYSTICK定时器做精确定时 delay_init(72); //调用LED初始化函数 LED_Init(); EXTI_Config(); //调用串口配置函数 USART_Config(); //调用数码管初始化函数 Displays_Init(); } 说明: 在Board_Init()函数之中,我们调用了其他源文件提供的初始化函数,其中就包含了数码管初始化函数。 10)修改Application()函数 voidApplication(void) { LED1_ON; LED2_ON; while (1) { Write_Displays(5.99); delay_ms(1000); Write_Displays(1234); delay_ms(1000); } } 11)修改main.c如下: #include"includes.h" intmain(void) { /*硬件初始化*/ Board_Init(); /*应用函数*/ Application(); /*正常情况下不会执行到这一步*/ return0; } 12)编译程序无误后通过JTAG下载到板子上并按下复位运行 7.实现现象 四位数码管一会显示05.99,一会显示1234. 课后思考 74HC595工作原理是什么?
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 机电传动控制 实验6数码管显示实验 机电 传动 控制 实验 数码管 显示
![提示](https://static.bdocx.com/images/bang_tan.gif)