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(二)

vfd with stm8的更多相关文章

  1. VFD 时钟(VFD Clock with STM8 v2.0)

    算是填了最先挖的VFD坑 最近pcb厂家神仙打架,为PCB普及做出了巨大贡献,到这事儿发生我也就开了两三次板,都赶上这个时间了,不开白不开! 不说了,上图! sch: pcb: 方案和之前的除了驱动电 ...

  2. vfd电子时钟制作

    17年也没干个啥,年后就去折腾着玩意儿了,也不知道我折腾它还是它折腾我.反正总之现在勉强可以交作业了,呵呵 硬件: 1.罗耶振荡电路输出一路4v交流,一路25v交流 其中4v直接驱动灯丝,另一路经电桥 ...

  3. STM8如何使用自带的bootloader

    1,首先确认你使用的STM8有没有自带的bootloader.参考下表 2,STM8空器件可以直接使用自带的bootloader. 3,STM8在使用SWIM烧录后,要想继续使用自带的bootload ...

  4. stm8的IIC库的使用

    一.前言 stm8是一款低功耗的MCU芯片,它具备stm32库函数和资源丰富的优势.也同时具有价格便宜,低功耗的特点.在一些项目中,能起到很好的作用.下面我介绍一下stm8的IIC硬件库函数驱动代码及 ...

  5. STM8 EEPROM:

    stm8的EEPROM的搽除是写0,FLASH_PRO与FLASH_DATA写的秘钥顺序相反 EEPROM读写前要解锁的.这个很简单,在技术文档里讲得很清楚.我用一个宏定义来代表EEPROM单元.#d ...

  6. 关于STM8空间不足的解决方法

    STM8虽然功能齐全,但是空间不足也是经常出来的情况.要么.text overflow,要么.bss overflow,让人头疼.这里把一些优化方案列出来,让空间得到充分利用: 1.在Project ...

  7. IAR 1.3 for STM8 ST-Link无法调试 无法仿真 the debugging session could not be started

    IAR 1.3 for STM8 ST-Link无法调试 the debugging session could not be started CPU型号是:STM8F103F3 首先要用ST Vis ...

  8. IAR ARM、IAR STM8、IAR MSP430共用一个IDE

    转自IAR ARM.IAR STM8.IAR MSP430共用一个IDE 试了安装好多个不同版本不同编译器的IAR,终于明白不同编译器的IAR共用IDE的条件,把几个不同编译器的IAR安装在一起,共用 ...

  9. 从零开始写驱动——vfd专用驱动芯片HT16514并行驱动程序编写

    前言 一直看别人搞的 vfd 很漂亮,前段时间淘了个 vfd 模块来,但没有模块资料,还好芯片没有打磨的,良心商家啊.周末抽空来研究一下这个东西. 从零开始 打开外壳 测试线路 查看芯片是 HT165 ...

随机推荐

  1. java造成内存泄露原因

    一.Java内存回收机制  不论哪种语言的内存分配方式,都需要返回所分配内存的真实地址,也就是返回一个指针到内存块的首地址.Java中对象是采用new或者反射的方法创建的,这些对象的创建都是在堆(He ...

  2. GROUP BY 的实现与优化

    由于GROUP BY实际上也同样需要进行排序操作,而且与ORDER BY相比,GROUP BY主要只是多了排序之后的分组操作.当然,如果在分组的时候还使用了其他的一些聚合函数,那么还需要一些聚合函数的 ...

  3. 从JDK源码角度看线程的阻塞和唤醒

    目前在Java语言层面能实现阻塞唤醒的方式一共有三种:suspend与resume组合.wait与notify组合.park与unpark组合.其中suspend与resume因为存在无法解决的竟态问 ...

  4. MongoDB分组

    MongoDB三种分组方式 group(先筛选再分组,不支持分片,对数据量有所限制,效率不高) [简单分组实测150W 12.5s] mapreduce(基于js引擎,单线程执行,效率较低,适合用做后 ...

  5. 7、Libgdx网络操作

    (官网:www.libgdx.cn) Libgdx包含了一些跨平台的网络操作类,这些类在Gdx.net中. 特性 跨平台HTTP请求 多平台TCP C/S Socket支持(可配置) TCP C/S优 ...

  6. (四十五)Modal 模态窗口 -遮盖

    任何控制器都能通过Modal方式切换. Modal的默认效果是:新显示的控制器从屏幕底部向上,直到盖住之前的控制器为止. 假设有One和Two两个控制器: One到Two的Modal方法:presen ...

  7. C++中const的实现细节介绍(C,C#同理)

    via:http://www.jb51.net/article/45755.htm 本篇文章主要是对C++中const的实现细节进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助 1.什么 ...

  8. RecyclerView notifyItem闪烁的问题

    之前我们做点赞,用listview做的话,就是在item实现点击后,写一个scal动画,不过现在都转到RecyclerView,那么要做这种效果于是做了一个notifyItemChanged()的操作 ...

  9. 【linux学习笔记之一】linux系统目录结构以及常用系统命令

    序 ???这破笔记也要序?? 昨天开始学linux,做好笔记以备日后翻阅 Linux系统目录结构图 bin  --主要用于存放二进制文件(如:命令文件) boot--引导目录 dev  --设备目录 ...

  10. mybatis配置开发

    以mysql为例: 一.需要的架包:mybatis.jar和mysql-connector-java.jar 二.一般会有两类配置文件:数据库配置文件和要执行的sql语句 数据库配置文件(配置文件中有 ...