点阵屏是一种使用较为广泛的信息显示器件,其主要是面向公共观众。
在使用时,通常是以多个模块串联拼接的方式来使用。这里使用的是一款16*63点的显示模块,它与开发板的连接关系为:
PB6 -- SCL---A
P B7 -- SDA---B
PA15 --RES---C
P B4 -- DC---D
PA6---OE
PA5---R1
PB9---STB
PB8---SCL
所使用的接口如图1所示:
图1 所用接口
相应引脚输出高低电平的语句定义为:
#define LA_high GPIO_WritePin(CW_GPIOB,
GPIO_PIN_6,GPIO_Pin_SET)
#define LA_low GPIO_WritePin(CW_GPIOB,
GPIO_PIN_6,GPIO_Pin_RESET)
#define LB_high GPIO_WritePin(CW_GPIOB,
GPIO_PIN_7,GPIO_Pin_SET)
#define LB_low GPIO_WritePin(CW_GPIOB,
GPIO_PIN_7,GPIO_Pin_RESET)
#define LC_high GPIO_WritePin(CW_GPIOA, GPIO_PIN_15,GPIO_Pin_SET)
#define LC_low GPIO_WritePin(CW_GPIOA,
GPIO_PIN_15,GPIO_Pin_RESET)
#define LD_high GPIO_WritePin(CW_GPIOB,
GPIO_PIN_4,GPIO_Pin_SET)
#define LD_low GPIO_WritePin(CW_GPIOB,
GPIO_PIN_4,GPIO_Pin_RESET)
#define LEN_high GPIO_WritePin(CW_GPIOA,
GPIO_PIN_6,GPIO_Pin_SET)
#define LEN_low GPIO_WritePin(CW_GPIOA,
GPIO_PIN_6,GPIO_Pin_RESET)
#define LR1_high GPIO_WritePin(CW_GPIOA,
GPIO_PIN_5,GPIO_Pin_SET)
#define LR1_low GPIO_WritePin(CW_GPIOA,
GPIO_PIN_5,GPIO_Pin_RESET)
#define LSTB_high GPIO_WritePin(CW_GPIOB,
GPIO_PIN_9,GPIO_Pin_SET)
#define LSTB_low GPIO_WritePin(CW_GPIOB,
GPIO_PIN_9,GPIO_Pin_RESET)
#define CLK_high GPIO_WritePin(CW_GPIOB,
GPIO_PIN_8,GPIO_Pin_SET)
#define CLK_low GPIO_WritePin(CW_GPIOB, GPIO_PIN_8,GPIO_Pin_RESET)
对所用引脚的配置函数为:
void dzp_gpio(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
__RCC_GPIOB_CLK_ENABLE();
GPIO_InitStruct.IT = GPIO_IT_NONE;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pins =GPIO_PIN_4|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_Init(CW_GPIOB, &GPIO_InitStruct);
__RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.IT= GPIO_IT_NONE;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pins= GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_15;
GPIO_InitStruct.Speed= GPIO_SPEED_HIGH;GPIO_Init(CW_GPIOA,&GPIO_InitStruct);
}
点阵屏发送数据的函数为:
void OutByte(uint16_t dat)
{
uint8_t i=0 ;
for(i=0;i<16;i++)
{
CLK_low;
if(dat&0x0001)
{
LR1_high;
}
else
{
LR1_low;
}
dat=dat>>1;
CLK_high;
}
}
发送各列数据的函数为:
void DisCol(uint16_t lenght)
{
uint16_t dat;
uint8_t m=0;
while(lenght--)
{
dat=(S[sj[m+1]*16+ScanRow]<<8)+S[sj[m]*16+ScanRow];
OutByte(dat);
m=m+2;
}
}
输出行地址的函数为:
void SeleRow(uint8_t Nd)
{
uint8_t N;
N=Nd;
N=N%16;
if(N&0x01) LA_high;
else LA_low;
if (N&0x02) LB_high;
else LB_low;
if (N&0x04) LC_high;
else LC_low;
if (N&0x08) LD_high;
else LD_low;
}
数值显示函数为:
void Display(void)
{
DisCol(4);
LEN_high;
LSTB_high;
LSTB_low;
SeleRow(ScanRow);
LEN_low;
ScanRow++;
if(ScanRow>15) ScanRow=0;
}
实现电子时钟显示牌功能的主程序为:
int32_t main(void)
{
RTC_InitTypeDef RTC_InitStruct;
RTC_TimeTypeDefRTC_TimeStruct;
RTC_AlarmTypeDef RTC_AlarmStruct;
RCC_Configuration();
dzp_gpio();
ScanRow=0;
NVIC_Configuration();
LogInit();
RCC_LSE_Enable(RCC_LSE_MODE_OSC,RCC_LSE_AMP_NORMAL, RCC_LSE_DRIVER_NORMAL);
RTC_InitStruct.DateStruct.Day= 0x21;
RTC_InitStruct.DateStruct.Month= RTC_Month_June;
RTC_InitStruct.DateStruct.Week= RTC_Weekday_Monday;
RTC_InitStruct.DateStruct.Year= 0x21;
RTC_InitStruct.TimeStruct.Hour= 0x2;
RTC_InitStruct.TimeStruct.Minute= 0x58;
RTC_InitStruct.TimeStruct.Second= 0x59;
RTC_InitStruct.TimeStruct.AMPM = 1;
RTC_InitStruct.TimeStruct.H24 = 0;
RTC_InitStruct.RTC_ClockSource =RTC_RTCCLK_FROM_LSE;
RTC_Init(&RTC_InitStruct);
RTC_AlarmStruct.RTC_AlarmMask =RTC_AlarmMask_WeekMON | RTC_AlarmMask_WeekTUE |RTC_AlarmMask_WeekWED |
RTC_AlarmMask_WeekTHU |RTC_AlarmMask_WeekFRI;
RTC_AlarmStruct.RTC_AlarmTime.Hour= 6;
RTC_AlarmStruct.RTC_AlarmTime.Minute= 0x45;
RTC_AlarmStruct.RTC_AlarmTime.Second= 0;
RTC_SetAlarm(RTC_Alarm_A,&RTC_AlarmStruct);
RTC_AlarmCmd(RTC_Alarm_A,ENABLE);
RTC_ITConfig(RTC_IT_ALARMA| RTC_IT_INTERVAL, ENABLE);
dzp_gpio();
ScanRow=0;
Display();
while(1)
{
RTC_GetTime(&RTC_TimeStruct);
sj[0]=RTC_TimeStruct.Hour/16;
sj[1]=RTC_TimeStruct.Hour%16%10;
sj[3]=RTC_TimeStruct.Minute/16;
sj[4]=RTC_TimeStruct.Minute%16%10;
sj[6]=RTC_TimeStruct.Second/16;
sj[7]=RTC_TimeStruct.Second%16%10;
Display();
}
}
经程序的编译与下载,其计时效果如图2和图3所示。
图2 计时效果1
图3计时效果2
演示视频: