STM32F103的数码管显示
Posted wlstm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32F103的数码管显示相关的知识,希望对你有一定的参考价值。
先来tm1629数码管驱动,网上看了一大堆,主要是共阴极的居多,共阴极操作简单,控制的数码管较少,共阳极的控制的数码管多,可是需要转换转换
TM16290.H
#ifndef __TM1629_H
#define __TM1629_H
#define TM1_STB_PIN GPIO_Pin_0
#define TM1_STB_PORT GPIOF
#define TM1_DIO_PIN GPIO_Pin_2
#define TM1_DIO_PORT GPIOF
#define TM1_CLK_PIN GPIO_Pin_1
#define TM1_CLK_PORT GPIOF
#define TM1_STB_H GPIO_SetBits(TM1_STB_PORT, TM1_STB_PIN)
#define TM1_STB_L GPIO_ResetBits(TM1_STB_PORT, TM1_STB_PIN)
#define TM1_DIO_H GPIO_SetBits(TM1_DIO_PORT, TM1_DIO_PIN)
#define TM1_DIO_L GPIO_ResetBits(TM1_DIO_PORT, TM1_DIO_PIN)
#define TM1_CLK_H GPIO_SetBits(TM1_CLK_PORT, TM1_CLK_PIN)
#define TM1_CLK_L GPIO_ResetBits(TM1_CLK_PORT, TM1_CLK_PIN)
#define READ_TM1_DIO GPIO_ReadInputDataBit(TM1_DIO_PORT, TM1_DIO_PIN)
/****************************public*********************************************************/
void tm1629a_gpio_init(void); //tm1629a端口初始化,推挽输出
void tm1629_init(void); //tm1629芯片初始化程序
/****************************private*********************************************************/
void tm1629SendByte(unsigned char data); //串行模式 MCU一次输出8个bit
void tm1629SendCmd(unsigned char cmd); //写命令
void tm1639_write(unsigned char *data );//打开TM1629并显示指定的数据
void write_tm1639_off(unsigned char *data );//关闭TM1629显示
void convert(unsigned char SrcNum, unsigned char *pDst , unsigned char seg, unsigned char dot);//共阳数码管数据格式转换 0~9转换
void convert2(unsigned char SrcNum, unsigned char *pDst , unsigned char seg); //共阳数码管数据格式转换 特殊格式转换
#endif
TM1629.C
#include "tm1629.h"
#include"stm32f10x.h" //只要调用库函数,就需要添加此头文件
#include"delay.h"
/****************************************************
*****************************************************
***********************public************************
*****************************************************
****************************************************/
/*tm1629端口初始化,3个端口都是推挽输出*/
void tm1629a_gpio_init(void){
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE); //使能PF端口时钟
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //TM1的STB挽输出
GPIO_InitStructure.GPIO_Pin=TM1_STB_PIN;
GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
GPIO_Init(TM1_STB_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=TM1_DIO_PIN; //TM1的DIO推挽输出
GPIO_Init(TM1_DIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=TM1_CLK_PIN; //TM1的CLK推挽输出
GPIO_Init(TM1_CLK_PORT, &GPIO_InitStructure);
}
/*启动tm1629必须有一个启动模式*/
void tm1629_init(void){
TM1_CLK_H;
TM1_DIO_H;
TM1_STB_H;
tm1629SendCmd(0x03); //写TM1629显示模式
tm1629SendCmd(0x40); //写数据到显示寄存器的方式采用地址自动加一
tm1629SendCmd(0x88); //开显示,亮度可以通过改变低三位调节
}
/****************************************************
*****************************************************
***********************private***********************
*****************************************************
****************************************************/
/*串行模式 在时钟的上升沿通过MCU向LED驱动IC——TM16xx写数据 */
void tm1629SendByte(unsigned char dat){
unsigned char i;
TM1_STB_L;//保证“STB”为低电平,程序不依赖于之前端口的状态;保证程序在实际运行中不会出现“端口迷失”
for(i=0;i<8;i++)
{
TM1_CLK_L; //clk置低,等待发送数据
if((dat & 0x01) == 0x01){ //传送最高位给DI
TM1_DIO_H; //需要传送的数据的低位为“1”,则把“DIO”置高
}
else{
TM1_DIO_L; //需要传送的数据的低位为“0”,则把“DIO”置零
}
delay_ms(1);
TM1_CLK_H; //送时钟的上升沿
dat >>= 1; //准备送下一个BIT
//delay_ms(1);
}
}
/*写命令*/
void tm1629SendCmd(unsigned char cmd){
TM1_STB_H;
TM1_CLK_H;
TM1_DIO_H; //通讯开始前通讯端口全部初始化为“1”
delay_ms(2);
TM1_STB_L; //片选(低电平)
tm1629SendByte(cmd);
TM1_STB_H;
}
/*打开TM1629并显示指定的数据*/
void tm1639_write(unsigned char *data ){
unsigned char i=0;
TM1_STB_H;
tm1629SendByte(0x40); //传数据设置命令,设置采用地址自动加一方式显示数据
TM1_STB_H;
tm1629SendByte(0xc0); //传送起始地址,地址命令传完后,“STB”保持为0继续传需要显示的数据
for(i=0;i<16;i++) //在连续显示的数据过程汇总,“STB”一直保持为0,
{
tm1629SendByte(data[i]);
}
TM1_STB_H; //传送完所有的显示数据后(最多14BYTE),将STB置1
tm1629SendByte(0x88);//0x8f //开显示,脉冲宽度为1/16 这个是最低的脉冲宽度
TM1_STB_H;
}
/*关闭TM1629显示*/
void write_tm1639_off(unsigned char *data ){
unsigned char i=0;
TM1_STB_H;
tm1629SendByte(0x40); //传数据设置命令,设置采用地址自动加一方式显示数据
TM1_STB_H;
tm1629SendByte(0xc0); //传送起始地址,地址命令传完后,“STB”保持为0继续传需要显示的数据
for(i=0;i<16;i++)
{
tm1629SendByte(data[i]);
}
TM1_STB_H;
tm1629SendByte(0x87); //关显示,脉冲宽度为14/16
TM1_STB_H;
}
/*共阳数码管数据格式转换
输入参数: SrcNum为0-9
pDst为转换后的数据
seg为当前数码管对应的sel管脚编号减1, 比如数码管片选接到芯片的SEG2,那么seg为1
dot为当前数码管是否带点显示
*/
void convert(unsigned char SrcNum, unsigned char *pDst , unsigned char seg, unsigned char dot){
unsigned char table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char i,uSrc;
if(dot == 0)
uSrc = table[SrcNum];
else
uSrc = table[SrcNum] | 0x80;
for(i=0; i<8; i++){ //一位一位移过去
if((uSrc & 0x01) == 1){//如果将要移过去的位是1,在对应的位置写1,紧跟着后一位写0
if(seg < 8){
pDst[2*i] = (1<<seg); //SEG<8,在地址的0、2、4、6、8、10、12、14写入有效数据
pDst[2*i + 1] = 0;//在地址的1、3、5、7、9、11、13、15填零
}
else if(seg > 7){
pDst[2*i] = 0;//SEG>8,在地址的0、2、4、6、8、10、12、14填零
pDst[2*i + 1] = (1<<(seg - 8));//在地址的1、3、5、7、9、11、13、15写入有效数字(9是左移1位,依次类推)
}
}
else{//如果将要移过去的位是0,在对应的位置写0,紧跟着后一位写0
pDst[2*i] = 0;
pDst[2*i + 1] = 0;
}
uSrc>>=1;//右移,移第二位
}
}
/*共阳数码管数据格式转换
特殊字符显示
输入参数: SrcNum为要显示的数据,比如要显示‘L’,用共阴的数据表示: h g f e d c b a 分别是 00111000(0x38)
pDst为转换后的数据
seg为当前数码管对应的sel管脚编号减1, 比如数码管片选接到芯片的SEG2,那么seg为1
a
f b
g
e c
d h
*/
void convert2(unsigned char SrcNum, unsigned char *pDst , unsigned char seg){
//uchar table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char i,uSrc;
uSrc = SrcNum;
for(i=0; i<8; i++)
{
if((uSrc & 0x01) == 1)
{
if(seg < 8)
{
pDst[2*i] = (1<<seg);
pDst[2*i + 1] = 0;
}
else if(seg > 7)
{
pDst[2*i] = 0;
pDst[2*i + 1] = (1<<(seg - 8));
}
}
else
{
pDst[2*i] = 0;
pDst[2*i + 1] = 0;
}
uSrc>>=1;
}
}
以上是关于STM32F103的数码管显示的主要内容,如果未能解决你的问题,请参考以下文章