vfd with stm8


2018-01-14 22:50:26


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

顺带熟悉了stm8的操作2333.

上源码:

 1 #ifndef PT6311_H
 2 #define PT6311_H
 3 
 4 #include "stm8s.h"
 5 #include "delay.h"
 6 #include "iostm8s103f3.h"        //inc the .h to use bit control
 7 
 8 
 9 extern u8 dspbuf[30],dspseg[13];
10 extern const u8 ADDR[30];        //addr
11 extern const u16 font[37];    //font
12 
13 #define GPS 0x08
14 #define ALARM 0x10
15 #define ALL 0x20
16 #define CONT 0x40
17 #define LP 0x80
18 
19 #define COLON 0x80    //personal protocal
20 #define CLR 36
21 //pin definition
22 #define DI     PC_ODR_ODR5        //@vfd board //for stm32 test//PCout(2)
23 #define DO    PC_IDR_IDR6                    //PCin(3)
24 #define CK    PC_ODR_ODR4                    //PCout(0)
25 #define STB PC_ODR_ODR3                    //PCout(13)
26 
27 void InitIo_PT6311(void);
28 void Init_PT6311(void);
29 void OpenStrobe_PT6311(void);
30 void WriteByte_PT6311(u8 dat);
31 u8 ReadByte_PT6311(void);
32 void TransCoding(void);//transcoding
33 unsigned int Pow2(u8 y);
34 #define CMD_ModeSetting 0x00
35 #define CMD_DataSetting 0x40
36 #define CMD_AddressSetting 0xc0
37 #define CMD_DisplaySetting 0x80
38 
39 #endif
  1 #include "pt6311.h"
  2 #include "stdio.h"
  3 
  4 //auth:katachi
  5 //time:2017-12-30
  6 //func:driver for pt6311
  7 //transplant to stm8 time:2018-1-14 17:
  8 const u8  ADDR[]={0x00,0x01,//digit 1
  9                             0x03,0x04,//digit 2
 10                             0x06,0x07,//digit 3
 11                             0x09,0x0a,//digit 4
 12                             0x0c,0x0d,//digit 5
 13                             0x0f,0x10,//digit 6
 14                             0x12,0x13,//digit 7
 15                             0x15,0x16,//digit 8
 16                             0x18,0x19,//digit 9
 17                             0x1B,0x1C,//digit 10
 18                             0x1E,0x1F,//digit 11
 19                             0x21,0x22,//digit 12
 20                             0x24,0x25,//digit 13
 21                             0x27,0x28,//digit 14
 22                             0x2a,0x2b};//digit 15
 23 const u16 font[37]={
 24     0x7266,0x2040,0x6186,0x61c2,0x23c0,0x43c2,0x43c6,0x5020,0x63c6,0x63c2,//0-9
 25     0x30e0,0x68d2,0x4206,0x6852,0x4386,0x4384,0x42ce,0x23c4,0x4812,0x2048,
 26     0x130c,0x206,0x3644,0x264c,0x6246,0x6384,0x624e,0x638c,0x43c2,0x4810,
 27     0x2246,0x1224,0x226c,0x1428,0x1410,0x5022,//a-z
 28     0};//: 
 29 u8 dspbuf[30],dspseg[13];
 30 unsigned int Pow2(u8 y)
 31 {
 32     u16 x=1;
 33     if (y)
 34     {
 35         while (y--)
 36             x*=2;
 37     }
 38     else
 39         x=1;
 40     return x;
 41 }
 42 void TransCoding(void)//recongnize num or char or with colon and transcoding the dspseg to pt6311 ram
 43 {
 44     u8 i=0,j=0;u16 tmp=0;
 45     
 46     for (i=0;i<30;i++)dspbuf[i]=0;//clrclr!!!!
 47      for (i=0;i<13;i++)//seg==i
 48  {
 49      if (i==0)    //for segment 0 display temp lvl
 50      {
 51             tmp=Pow2(dspseg[0]) - 1;    
 52             tmp<<=4;    
 53      }
 54      else if (i==12)//for ui
 55      {
 56         //dspseg[12]    8bit
 57         //            _                         _                 _        _        ,    _     _ _ _
 58         //  LOWPOWER   CONTINUPAUSE ALL  ALARM  GPS    WEEK
 59          j=dspseg[12];
 60 
 61          if (j&0x08)//GPS
 62              tmp=0x80;    //=
 63          if (j&0x10)//ALARM
 64              tmp|=0x20;    //|=
 65          if (j&0x20)//ALL
 66              tmp|=0x300;
 67          if (j&0x40)//CT
 68              tmp|=0xc00;
 69          if (j&0x80)//LP
 70              tmp|=0x7000;
 71          j&=0x07;//get week
 72          j--;
 73          if (j>4)//sat sun
 74              tmp|=j+1;
 75          else        //mon to fri
 76              tmp|=1<<j;
 77      }
 78      else
 79      {
 80          //tmp=font['p'-87+i];//ascii to personal font
 81          if (dspseg[i]>0x80)//num with colon
 82          {
 83              dspseg[i]-=0x80;
 84             tmp=font[dspseg[i]]+1;
 85          }
 86          else if (dspseg[i]>90 && dspseg[i]<0x80)//charac
 87              tmp=font[dspseg[i]-87];
 88          else
 89                 tmp=font[dspseg[i]];//plain num
 90         }
 91      //transcoding
 92      if(i<8)
 93      {
 94             for (j=0;j<15;j++)
 95          {
 96                 dspbuf[2*j]|=(tmp&0x1)<<i;
 97                 tmp>>=1;     
 98          }
 99     }
100      else
101      {
102             for (j=1;j<16;j++)
103          {
104                 dspbuf[2*j-1]|=(tmp&0x1)<<(i-8);
105                 tmp>>=1;     
106          }        
107      }
108  }
109 }
110 void OpenStrobe_PT6311(void)
111 {
112     STB=1;
113     delay_us(1);
114     STB=0;
115 }
116 void InitIo_PT6311()
117 {//from stm32
118 //    GPIO_InitTypeDef  GPIO_InitStructure;
119 //
120 //    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);    //enable portc
121 //
122 //    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_2|GPIO_Pin_13;                
123 //    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;          //ppout
124 //    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;         //
125 //    GPIO_Init(GPIOC, &GPIO_InitStructure);                     
126 //
127 //    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;                
128 //    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
129 //    GPIO_Init(GPIOC, &GPIO_InitStructure);
130 //move to stm8
131   GPIO_Init(GPIOC,(GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5),GPIO_MODE_OUT_PP_HIGH_FAST);//portC 345 pp mode 
132   GPIO_Init(GPIOC,(GPIO_PIN_6),GPIO_MODE_IN_FL_NO_IT);//portC 6 FLin
133 }
134 void Init_PT6311(void)
135 {
136     u8 i;
137     
138     InitIo_PT6311();
139     
140     OpenStrobe_PT6311();
141     WriteByte_PT6311(CMD_ModeSetting|0x0e);//15digits 13sg
142 
143     OpenStrobe_PT6311();
144     WriteByte_PT6311(CMD_DataSetting|0x04);    //fixed addr
145 
146     for (i=0;i<30;i++)
147     {
148         OpenStrobe_PT6311();
149         WriteByte_PT6311(CMD_AddressSetting|ADDR[i]);        
150             WriteByte_PT6311(0x00);
151     }
152     
153     OpenStrobe_PT6311();
154     WriteByte_PT6311(CMD_DisplaySetting|0x0f);//on 14/16
155 }
156 void WriteByte_PT6311(u8 dat)
157 {
158     u8 i;
159 
160     CK=1;//de-pulldown
161     for (i=0;i<8;i++)
162     {
163         CK=0;    //>>200ns
164         DI=dat&0x01;        //send a bit to pt6311's data in pin
165         dat>>=1;                //lsb first
166         CK=1;
167     }
168 }
169 u8 ReadByte_PT6311(void)
170 {
171     u8 dat,i;
172     CK=1;
173     delay_us(2);
174     for (i=0;i<8;i++)
175     {
176         CK=0;//while (j++<10);
177         delay_us(1);//tplz tpzl
178         dat>>=1;                //lsb first
179         if (DO)
180             dat|=0x80;                //catch a bit from pt6311's data out pin
181         CK=1;
182     }
183     delay_us(1);//tclk stb
184     return dat;
185 }

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

 1 #ifndef  __DELAY_H
 2 #define  __DELAY_H
 3 
 4 ////////////////////////////////////////////////////////////////////////////////  
 5 //使用汇编代码进行精确延时处理
 6 //包括delay_us,delay_ms
 7 #include "stm8s.h"
 8 
 9 void delay_init(u8 clk); //延时函数初始化
10 void delay_us(u16 nus);  //us级延时函数,最大65536us.
11 void delay_ms(u32 nms);  //ms级延时函数
12 #endif
 1 #include "delay.h"
 2 
 3 
 4 
 5 volatile u8 fac_us=0; //us延时倍乘数  
 6 
 7 //延时函数初始化
 8 //为确保准确度,请保证时钟频率最好为4的倍数,最低8Mhz
 9 //clk:时钟频率(24/16/12/8等) 
10 void delay_init(u8 clk)
11 {
12  if(clk>16)fac_us=(16-4)/4;//24Mhz时,stm8大概19个周期为1us
13  else if(clk>4)fac_us=(clk-4)/4; 
14  else fac_us=1;
15 }
16 //延时nus
17 //延时时间=(fac_us*4+4)*nus*(T)
18 //其中,T为CPU运行频率(Mhz)的倒数,单位为us.
19 //准确度:
20 //92%  @24Mhz
21 //98%  @16Mhz
22 //98%  @12Mhz
23 //86%  @8Mhz
24 void delay_us(u16 nus)
25 {  
26 __asm(
27 "PUSH A          \n"  //1T,压栈
28 "DELAY_XUS:      \n"   
29 "LD A,fac_us     \n"   //1T,fac_us加载到累加器A
30 "DELAY_US_1:     \n"  
31 "NOP             \n"  //1T,nop延时
32 "DEC A           \n"  //1T,A--
33 "JRNE DELAY_US_1 \n"   //不等于0,则跳转(2T)到DELAY_US_1继续执行,若等于0,则不跳转(1T).
34 "NOP             \n"  //1T,nop延时
35 "DECW X          \n"  //1T,x--
36 "JRNE DELAY_XUS  \n"    //不等于0,则跳转(2T)到DELAY_XUS继续执行,若等于0,则不跳转(1T).
37 "POP A           \n"  //1T,出栈
38 ); 
39 } 
40 //延时nms  
41 //为保证准确度,nms不要大于16640.
42 void delay_ms(u32 nms)
43 {
44  u8 t;
45  if(nms>65)
46  {
47   t=nms/65;
48   while(t--)delay_us(65000);
49   nms=nms%65;
50  }
51  delay_us(nms*1000);
52 }

最后上主函数,这是调试的程序,乱的一笔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(16);//@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[0]=10;//temp
    dspseg[1]='h';
    dspseg[2]='e';dspseg[3]='l';
    dspseg[4]='l';dspseg[5]='o';
     dspseg[6]='i';dspseg[7]='t';
     dspseg[8]='s';dspseg[9]='m';
     dspseg[10]='e';dspseg[11]='w';
    dspseg[12]=CONT|ALL|2;//ui
    TransCoding();
                     OpenStrobe_PT6311();
                WriteByte_PT6311(CMD_ModeSetting|0x0e);//15digits 13sg

                OpenStrobe_PT6311();
                WriteByte_PT6311(CMD_DataSetting|0x04);    //fixed addr
                
                for (len=0;len<30;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=1;
   while (1)
   {     
     dspseg[1]=i/100;
     dspseg[2]=i/10%10;
     dspseg[3]=i%10;
     delay_ms(1000);
     TransCoding();
                OpenStrobe_PT6311();
                WriteByte_PT6311(CMD_DataSetting|0x04);    //fixed addr
                
                for (len=0;len<30;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)==0)
            {printf("open led");
                OpenStrobe_PT6311();
                for (i=0;i<4;i++)
                {
                    WriteByte_PT6311(CMD_DataSetting|0x01);
                    WriteByte_PT6311(~(1<<i));//open led
                    delay_ms(100);
                }
                for (i=0;i<4;i++)
                {
                    WriteByte_PT6311(CMD_DataSetting|0x01);
                    WriteByte_PT6311(~(0x4>>i));//open led
                    delay_ms(100);
                }
            }else
            if (strcmp("ds",RxBuffer)==0)
            {
                OpenStrobe_PT6311();
                WriteByte_PT6311(CMD_DataSetting|0x04);    //fixed addr
                
                for (i=0;i<30;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=1;
            }else
            if (strcmp("key",RxBuffer)==0)
            {
            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=0;t<len;t++)
              RxBuffer[t]=0;
         UART_RX_NUM=0;//clr
      }
    }
}

void Delay(u32 nCount)
{
  /* Decrement nCount value */
  while (nCount != 0)
  {
    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 (1)
  {
  }
}
#endif

没啥可说的,

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

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

 

posted @ 2018-01-14 22:58  katachi  阅读(767)  评论(0编辑  收藏  举报