完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
STM32硬件SPI控制TM1638按键数码管LED显示模块
从淘宝买来的,TM1638专门是控制LED的,LED组合起来就可以变成数码管,还有按键,这个我就没管了,不想管了,发这个帖子只是为了记录下经验,待以后会过头来看的时候,可以一遍就知道,所以尽量写得详细点。 手头上的项目用的是共阳极,而我买的是共阴极的,而且例程给的是STM32模拟IO实现的。 太浪费资源了,想尽办法折腾了1整体,终于搞定了SPI硬件实现的方式。写点东西给大家分享下,免得走弯路。本次重点介绍SPI硬件配置方面。 先来个照片,是共阴极的 原理图 废话不多说了,开始贴程序。 3.3V供电; STM32F103c8t6; SPI1; SPI_Direction_1Line_Tx; 完整程序如下: //TM1638.C文件 #ifdef USE_TM1638_SPI #defineTM1638_SPIx SPI1 #defineTM1638_SPI_APBxClock_FUN RCC_APB2PeriphClockCmd #defineTM1638_SPI_CLK RCC_APB2Periph_SPI1 #defineTM1638_SPI_GPIO_APBxClock_FUN RCC_APB2PeriphClockCmd #defineTM1638_SPI_GPIO_CLK RCC_APB2Periph_GPIOA #defineTM1638_SPI_SCK_PORT GPIOA #defineTM1638_SPI_SCK_PIN GPIO_Pin_5 #defineTM1638_SPI_SCK_Low() GPIO_ResetBits(TM1638_SPI_SCK_PORT, TM1638_SPI_SCK_PIN) #defineTM1638_SPI_SCK_High() GPIO_SetBits(TM1638_SPI_SCK_PORT, TM1638_SPI_SCK_PIN) #defineTM1638_SPI_MISO_PORT GPIOA #defineTM1638_SPI_MISO_PIN GPIO_Pin_6 #defineTM1638_SPI_MOSI_PORT GPIOA #defineTM1638_SPI_MOSI_PIN GPIO_Pin_7 #defineTM1638_SPI_MOSI_Low() GPIO_ResetBits(TM1638_SPI_MOSI_PORT, TM1638_SPI_MOSI_PIN) #defineTM1638_SPI_MOSI_High() GPIO_SetBits(TM1638_SPI_MOSI_PORT, TM1638_SPI_MOSI_PIN) #defineTM1638_SPI_CS_CLK RCC_APB2Periph_GPIOA #defineTM1638_SPI_CS_PORT GPIOA #defineTM1638_SPI_CS_PIN GPIO_Pin_3 #defineTM1638_SPI_CS_ENABLE() GPIO_ResetBits(TM1638_SPI_CS_PORT, TM1638_SPI_CS_PIN) #defineTM1638_SPI_CS_DISABLE() GPIO_SetBits(TM1638_SPI_CS_PORT, TM1638_SPI_CS_PIN) #defineTM1638_CE_CLK RCC_APB2Periph_GPIOA #defineTM1638_CE_PORT GPIOA #defineTM1638_CE_PIN GPIO_Pin_3 #defineTM1638_CE_LOW() GPIO_ResetBits(TM1638_CE_PORT, TM1638_CE_PIN) #defineTM1638_CE_HIGH() GPIO_SetBits(TM1638_CE_PORT, TM1638_CE_PIN) #defineTM1638_IRQ_CLK RCC_APB2Periph_GPIOA #defineTM1638_IRQ_PORT GPIOA #defineTM1638_IRQ_PIN GPIO_Pin_2 #defineTM1638_IRQ_PIN_READ() GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2) voidTM1638_GPIO_init(void) { GPIO_InitTypeDef GPIO_InitStructure; SPI_InitTypeDef SPI_InitStructure; TM1638_SPI_APBxClock_FUN(TM1638_SPI_CLK,ENABLE); TM1638_SPI_GPIO_APBxClock_FUN(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitStructure.GPIO_Pin =GPIO_Pin_5|GPIO_Pin_7|GPIO_Pin_6; //PB12上拉防止W25X的干扰 GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化指定IO GPIO_InitStructure.GPIO_Pin= GPIO_Pin_4|GPIO_Pin_3; //PB12上拉防止W25X的干扰 GPIO_InitStructure.GPIO_Mode= GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化指定IO TM1638_SPI_CS_DISABLE(); //SPI片选取消 SPI_Cmd(TM1638_SPIx, DISABLE); // SPI外设不使能 SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; //SPI设置为双线双向全双工 SPI_InitStructure.SPI_Mode =SPI_Mode_Master; //SPI主机 SPI_InitStructure.SPI_DataSize =SPI_DataSize_8b; //发送接收8位帧结构 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //时钟悬空低 SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //数据捕获于第1个时钟沿 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由软件控制 SPI_InitStructure.SPI_BaudRatePrescaler =SPI_BaudRatePrescaler_4; //定义波特率预分频的值:波特率预分频值为16 SPI_InitStructure.SPI_FirstBit =SPI_FirstBit_LSB;//SPI_FirstBit_MSB; //数据传输从MSB位开始 SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式 SPI_Init(TM1638_SPIx,&SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器 SPI_Cmd(TM1638_SPIx, ENABLE); //使能SPI外设 //TM1638_CE_HIGH() ; TM1638_SPI_CS_ENABLE(); //SPI片选取消 } void TM1638_SPIx_SetSpeed(SPI_TypeDef*SPIx, uint8_t SPI_BaudRatePrescaler) { /* Check the parameters */ assert_param(IS_SPI_ALL_PERIPH(SPIx)); assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler)); SPIx->CR1&=0XFFC7; SPIx->CR1|=SPI_BaudRatePrescaler; //设置SPI2速度 SPI_Cmd(SPIx,ENABLE); } uint8_tTM1638_SPIx_ReadWriteByte(SPI_TypeDef* SPIx, uint8_t TxData) { SPI_I2S_SendData(SPIx, TxData); //通过外设SPIx发送一个数据 while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY) == RESET);//等待发送完成 } void TM1638_Write_Reg(uint8_t value) { TM1638_SPI_CS_ENABLE(); //使能SPI传输 TM1638_SPIx_ReadWriteByte(TM1638_SPIx,value); //写入寄存器的值 TM1638_SPI_CS_DISABLE(); //禁止SPI传输 } voidWrite_DATA(unsigned char add,unsigned char DATA) //指定地址写入数据 { TM1638_Write_Reg(0x44); TM1638_SPI_CS_ENABLE() ; //TM1638_Write(0xc0|add); TM1638_SPIx_ReadWriteByte(TM1638_SPIx,0xc0|add); //设置起始地址 TM1638_SPIx_ReadWriteByte(TM1638_SPIx,DATA); //设置起始地址 //TM1638_Write(DATA); TM1638_SPI_CS_DISABLE(); } /* voidWrite_oneLED(unsigned char num,unsigned char flag) //单独控制一个LED函数,num为需要控制的led序号,flag为0时熄灭,不为0时点亮 { if(flag) Write_DATA(2*num+1,1); else Write_DATA(2*num+1,0); } */ voidWrite_allLED(unsigned char LED_flag) //控制全部LED函数,LED_flag表示各个LED状态 { unsigned char i; for(i=0;i<8;i++) { if(LED_flag&(1< //Write_DATA(2*i+1,3); Write_DATA(2*i+1,1); else Write_DATA(2*i+1,0); } } voidinit_TM1638(void) { unsigned char i; TM1638_GPIO_init(); TM1638_SPIx_SetSpeed(TM1638_SPIx,SPI_BaudRatePrescaler_4);//spi速度为9Mhz(24L01的最大SPI时钟为10Mhz) TM1638_Write_Reg(0x8b); //亮度 (0x88-0x8f)8级亮度可调 TM1638_Write_Reg(0x40); //采用地址自动加1 TM1638_SPI_CS_ENABLE() ; // TM1638_SPIx_ReadWriteByte(TM1638_SPIx,0xc0); //设置起始地址 for(i=0;i<16;i++) //传送16个字节的数据 TM1638_SPIx_ReadWriteByte(TM1638_SPIx,0x00); TM1638_SPI_CS_DISABLE(); } #endif //main.C文件 /* 包含头文件 ----------------------------------------------------------------*/ #include"stm32f10x.h" #include"bsp/usart/bsp_debug_usart.h" #include"bsp/NRF24l01/NRF24l01.h" #include"bsp/TM1638/bsp_tm1638.h" unsignedchar LedTab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07, 0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71}; /* 私有类型定义 --------------------------------------------------------------*/ /* 私有宏定义 ----------------------------------------------------------------*/ /* 私有变量 ------------------------------------------------------------------*/ /* 扩展变量------------------------------------------------------------------*/ /* 私有函数原形 --------------------------------------------------------------*/ staticvoid Delay(uint32_t time); /* 函数体 --------------------------------------------------------------------*/ /** * 函数功能: 主函数. * 输入参数: 无 * 返 回 值: 无 * 说 明: 无 */ intmain(void) { uint8_ti; uint8_t tmp_buf[33; unsigned char num[8]; //各个数码管显示的值 /* 调试串口初始化配置,115200-N-8-1.使能串口发送和接受 */ DEBUG_USART_Init(); /* 调用格式化输出函数打印输出数据 */ printf("这是一个NRF24L012.4G无线数据传输模块测试实验n"); init_TM1638(); /* 无限循环 */ Delay(200); for(i=0;i<8;i++) Write_DATA(i<<1,tab[0]); //初始化寄存器 while(1) { Delay(100); if(i<8) { num++; //while(Read_key()==i); //等待按键释放 if(num>15) num=0; Write_DATA(i*2,tab[num]); Write_allLED(1< i++; //读按键值 } else i= 0; } } /** * 函数功能: 简单粗暴的延时函数 * 输入参数: time;延时时间设置 * 返 回 值: 无 * 说 明:使用这种死循环方式的延时函数是没办法精确控制延时时间长短, * 只是大概的延时时间,所以基本上都是通过不断修改输入参数 * 大小然后下载到开发板上看实验效果。 */ staticvoid Delay(uint32_t time) { uint32_t i,j; for(i=0;i { for(j=0;j<10000;++j) { //空循环,什么都不做 } } } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1780 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1621 浏览 1 评论
1081 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
728 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1679 浏览 2 评论
1938浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
731浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
570浏览 3评论
596浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
556浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-24 02:47 , Processed in 1.102236 second(s), Total 78, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号