vfd with stm8

时间:2023-03-08 17:43:28
vfd with stm8

2018-01-14 22:50:26


之前写了pt6311的驱动,要做时钟考虑使用stm8做主控,于是乎将之前的驱动移植到stm8上。

顺带熟悉了stm8的操作2333.

上源码:

 #ifndef PT6311_H
#define PT6311_H #include "stm8s.h"
#include "delay.h"
#include "iostm8s103f3.h" //inc the .h to use bit control extern u8 dspbuf[],dspseg[];
extern const u8 ADDR[]; //addr
extern const u16 font[]; //font #define GPS 0x08
#define ALARM 0x10
#define ALL 0x20
#define CONT 0x40
#define LP 0x80 #define COLON 0x80 //personal protocal
#define CLR 36
//pin definition
#define DI PC_ODR_ODR5 //@vfd board //for stm32 test//PCout(2)
#define DO PC_IDR_IDR6 //PCin(3)
#define CK PC_ODR_ODR4 //PCout(0)
#define STB PC_ODR_ODR3 //PCout(13) void InitIo_PT6311(void);
void Init_PT6311(void);
void OpenStrobe_PT6311(void);
void WriteByte_PT6311(u8 dat);
u8 ReadByte_PT6311(void);
void TransCoding(void);//transcoding
unsigned int Pow2(u8 y);
#define CMD_ModeSetting 0x00
#define CMD_DataSetting 0x40
#define CMD_AddressSetting 0xc0
#define CMD_DisplaySetting 0x80 #endif
 #include "pt6311.h"
#include "stdio.h" //auth:katachi
//time:2017-12-30
//func:driver for pt6311
//transplant to stm8 time:2018-1-14 17:
const u8 ADDR[]={0x00,0x01,//digit 1
0x03,0x04,//digit 2
0x06,0x07,//digit 3
0x09,0x0a,//digit 4
0x0c,0x0d,//digit 5
0x0f,0x10,//digit 6
0x12,0x13,//digit 7
0x15,0x16,//digit 8
0x18,0x19,//digit 9
0x1B,0x1C,//digit 10
0x1E,0x1F,//digit 11
0x21,0x22,//digit 12
0x24,0x25,//digit 13
0x27,0x28,//digit 14
0x2a,0x2b};//digit 15
const u16 font[]={
0x7266,0x2040,0x6186,0x61c2,0x23c0,0x43c2,0x43c6,0x5020,0x63c6,0x63c2,//0-9
0x30e0,0x68d2,0x4206,0x6852,0x4386,0x4384,0x42ce,0x23c4,0x4812,0x2048,
0x130c,0x206,0x3644,0x264c,0x6246,0x6384,0x624e,0x638c,0x43c2,0x4810,
0x2246,0x1224,0x226c,0x1428,0x1410,0x5022,//a-z
};//:
u8 dspbuf[],dspseg[];
unsigned int Pow2(u8 y)
{
u16 x=;
if (y)
{
while (y--)
x*=;
}
else
x=;
return x;
}
void TransCoding(void)//recongnize num or char or with colon and transcoding the dspseg to pt6311 ram
{
u8 i=,j=;u16 tmp=; for (i=;i<;i++)dspbuf[i]=;//clrclr!!!!
for (i=;i<;i++)//seg==i
{
if (i==) //for segment 0 display temp lvl
{
tmp=Pow2(dspseg[]) - ;
tmp<<=;
}
else if (i==)//for ui
{
//dspseg[12] 8bit
// _ _ _ _ , _ _ _ _
// LOWPOWER CONTINUPAUSE ALL ALARM GPS WEEK
j=dspseg[]; if (j&0x08)//GPS
tmp=0x80; //=
if (j&0x10)//ALARM
tmp|=0x20; //|=
if (j&0x20)//ALL
tmp|=0x300;
if (j&0x40)//CT
tmp|=0xc00;
if (j&0x80)//LP
tmp|=0x7000;
j&=0x07;//get week
j--;
if (j>)//sat sun
tmp|=j+;
else //mon to fri
tmp|=<<j;
}
else
{
//tmp=font['p'-87+i];//ascii to personal font
if (dspseg[i]>0x80)//num with colon
{
dspseg[i]-=0x80;
tmp=font[dspseg[i]]+;
}
else if (dspseg[i]> && dspseg[i]<0x80)//charac
tmp=font[dspseg[i]-];
else
tmp=font[dspseg[i]];//plain num
}
//transcoding
if(i<)
{
for (j=;j<;j++)
{
dspbuf[*j]|=(tmp&0x1)<<i;
tmp>>=;
}
}
else
{
for (j=;j<;j++)
{
dspbuf[*j-]|=(tmp&0x1)<<(i-);
tmp>>=;
}
}
}
}
void OpenStrobe_PT6311(void)
{
STB=;
delay_us();
STB=;
}
void InitIo_PT6311()
{//from stm32
// GPIO_InitTypeDef GPIO_InitStructure;
//
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //enable portc
//
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_2|GPIO_Pin_13;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //ppout
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //
// GPIO_Init(GPIOC, &GPIO_InitStructure);
//
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
// GPIO_Init(GPIOC, &GPIO_InitStructure);
//move to stm8
GPIO_Init(GPIOC,(GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5),GPIO_MODE_OUT_PP_HIGH_FAST);//portC 345 pp mode
GPIO_Init(GPIOC,(GPIO_PIN_6),GPIO_MODE_IN_FL_NO_IT);//portC 6 FLin
}
void Init_PT6311(void)
{
u8 i; InitIo_PT6311(); OpenStrobe_PT6311();
WriteByte_PT6311(CMD_ModeSetting|0x0e);//15digits 13sg OpenStrobe_PT6311();
WriteByte_PT6311(CMD_DataSetting|0x04); //fixed addr for (i=;i<;i++)
{
OpenStrobe_PT6311();
WriteByte_PT6311(CMD_AddressSetting|ADDR[i]);
WriteByte_PT6311(0x00);
} OpenStrobe_PT6311();
WriteByte_PT6311(CMD_DisplaySetting|0x0f);//on 14/16
}
void WriteByte_PT6311(u8 dat)
{
u8 i; CK=;//de-pulldown
for (i=;i<;i++)
{
CK=; //>>200ns
DI=dat&0x01; //send a bit to pt6311's data in pin
dat>>=; //lsb first
CK=;
}
}
u8 ReadByte_PT6311(void)
{
u8 dat,i;
CK=;
delay_us();
for (i=;i<;i++)
{
CK=;//while (j++<10);
delay_us();//tplz tpzl
dat>>=; //lsb first
if (DO)
dat|=0x80; //catch a bit from pt6311's data out pin
CK=;
}
delay_us();//tclk stb
return dat;
}

用到了原子哥写的stm8精确软件延时,感谢!!!

 #ifndef  __DELAY_H
#define __DELAY_H ////////////////////////////////////////////////////////////////////////////////
//使用汇编代码进行精确延时处理
//包括delay_us,delay_ms
#include "stm8s.h" void delay_init(u8 clk); //延时函数初始化
void delay_us(u16 nus); //us级延时函数,最大65536us.
void delay_ms(u32 nms); //ms级延时函数
#endif
 #include "delay.h"

 volatile u8 fac_us=; //us延时倍乘数  

 //延时函数初始化
//为确保准确度,请保证时钟频率最好为4的倍数,最低8Mhz
//clk:时钟频率(24/16/12/8等)
void delay_init(u8 clk)
{
if(clk>)fac_us=(-)/;//24Mhz时,stm8大概19个周期为1us
else if(clk>)fac_us=(clk-)/;
else fac_us=;
}
//延时nus
//延时时间=(fac_us*4+4)*nus*(T)
//其中,T为CPU运行频率(Mhz)的倒数,单位为us.
//准确度:
//92% @24Mhz
//98% @16Mhz
//98% @12Mhz
//86% @8Mhz
void delay_us(u16 nus)
{
__asm(
"PUSH A \n" //1T,压栈
"DELAY_XUS: \n"
"LD A,fac_us \n" //1T,fac_us加载到累加器A
"DELAY_US_1: \n"
"NOP \n" //1T,nop延时
"DEC A \n" //1T,A--
"JRNE DELAY_US_1 \n" //不等于0,则跳转(2T)到DELAY_US_1继续执行,若等于0,则不跳转(1T).
"NOP \n" //1T,nop延时
"DECW X \n" //1T,x--
"JRNE DELAY_XUS \n" //不等于0,则跳转(2T)到DELAY_XUS继续执行,若等于0,则不跳转(1T).
"POP A \n" //1T,出栈
);
}
//延时nms
//为保证准确度,nms不要大于16640.
void delay_ms(u32 nms)
{
u8 t;
if(nms>)
{
t=nms/;
while(t--)delay_us();
nms=nms%;
}
delay_us(nms*);
}

最后上主函数,这是调试的程序,乱的一笔233333

#include "stm8s.h"
#include "stm8s_clk.h"
#include "intrinsics.h"
#include "stm8s_uart1.h"
#include "uart.h"
#include "sysclock.h"
#include "delay.h" #include "pt6311.h"
#include "led.h"
#include "string.h" void Delay(u32 nCount);
extern u8 RxBuffer[RxBufferSize];
extern u8 UART_RX_NUM;
int main(void)
{
u8 len,i,t;
//use this fuction to choose a clock
SystemClock_Init(HSI_Clock); //hsi //CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); /*!<Set High speed internal clock */
Uart_Init();
//added
delay_init();//@delay.c
LED_Init();//@gpio.c
__enable_interrupt();
printf("\r\nSystem Clock Frequency is:%ld Hz\r\n",CLK_GetClockFreq());//print the clock
printf("vfd test\r\n"); Init_PT6311();
dspseg[]=;//temp
dspseg[]='h';
dspseg[]='e';dspseg[]='l';
dspseg[]='l';dspseg[]='o';
dspseg[]='i';dspseg[]='t';
dspseg[]='s';dspseg[]='m';
dspseg[]='e';dspseg[]='w';
dspseg[]=CONT|ALL|;//ui
TransCoding();
OpenStrobe_PT6311();
WriteByte_PT6311(CMD_ModeSetting|0x0e);//15digits 13sg OpenStrobe_PT6311();
WriteByte_PT6311(CMD_DataSetting|0x04); //fixed addr for (len=;len<;len++)
{
OpenStrobe_PT6311();
WriteByte_PT6311(CMD_AddressSetting|ADDR[len]);
WriteByte_PT6311(dspbuf[len]);
}
OpenStrobe_PT6311();
WriteByte_PT6311(CMD_DisplaySetting|0x08|0x07);//on 14/16
STB=;
while ()
{
dspseg[]=i/;
dspseg[]=i/%;
dspseg[]=i%;
delay_ms();
TransCoding();
OpenStrobe_PT6311();
WriteByte_PT6311(CMD_DataSetting|0x04); //fixed addr for (len=;len<;len++)
{
OpenStrobe_PT6311();
WriteByte_PT6311(CMD_AddressSetting|ADDR[len]);
WriteByte_PT6311(dspbuf[len]);
}
i++;
if(UART_RX_NUM&0x80)
{
led=!led;
len=UART_RX_NUM&0x3f;/*得到此次接收到的数据长度*/
printf("\r\nWhat you have in put is:\r\n");
UART1_SendString(RxBuffer,len);
UART1_SendByte('\r\n');
if (strcmp("led",RxBuffer)==)
{printf("open led");
OpenStrobe_PT6311();
for (i=;i<;i++)
{
WriteByte_PT6311(CMD_DataSetting|0x01);
WriteByte_PT6311(~(<<i));//open led
delay_ms();
}
for (i=;i<;i++)
{
WriteByte_PT6311(CMD_DataSetting|0x01);
WriteByte_PT6311(~(0x4>>i));//open led
delay_ms();
}
}else
if (strcmp("ds",RxBuffer)==)
{
OpenStrobe_PT6311();
WriteByte_PT6311(CMD_DataSetting|0x04); //fixed addr for (i=;i<;i++)
{
OpenStrobe_PT6311();
WriteByte_PT6311(CMD_AddressSetting|ADDR[i]);
WriteByte_PT6311(dspbuf[i]);
}
OpenStrobe_PT6311();
WriteByte_PT6311(CMD_DisplaySetting|0x08|0x07);//on 14/16
STB=;
}else
if (strcmp("key",RxBuffer)==)
{
OpenStrobe_PT6311();
WriteByte_PT6311(CMD_DisplaySetting|0x07);//on 14/16
OpenStrobe_PT6311();
WriteByte_PT6311(CMD_DataSetting|0x02);
t=ReadByte_PT6311(),
printf("keyval %d",t);
}
//clr
for (t=;t<len;t++)
RxBuffer[t]=;
UART_RX_NUM=;//clr
}
}
} void Delay(u32 nCount)
{
/* Decrement nCount value */
while (nCount != )
{
nCount--;
}
} #ifdef USE_FULL_ASSERT /**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval : None
*/
void assert_failed(u8* file, u32 line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* Infinite loop */
while ()
{
}
}
#endif

没啥可说的,

用到我写的驱动,修改版的头文件实现按位操作io,原子哥的精确软件延时,串口调程序

详细驱动讲解,见另一篇博文 vfd(二)