vfd折腾(二)
这篇是前期程序部分,主要讲驱动pt6311的程序
电路见上一篇博文
#ifndef PT6311_H
#define PT6311_H #include "sys.h"
#include "delay.h"
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
#define DI PCout(2)
#define DO PCin(3)
#define CLK PCout(0)
#define STB 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
//定义io以及声明一些实现函数
#include "pt6311.h"
#include "stdio.h"
//auth:katachi
//time:2017-12-30
//func:driver for pt6311
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;
//2018年1月14日22点44分已修改
for (i=0;i<30;i++)dspbuf[i]=0;
//起初只运行了一次这个函数,没发现这个bug 因为用的全是或运算,如某位上次为1那么一直为1
//加这句清零
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()
{
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);
}
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(0xff);
} OpenStrobe_PT6311();
WriteByte_PT6311(CMD_DisplaySetting|0x0f);//on 14/16
}
void WriteByte_PT6311(u8 dat)
{
u8 i; CLK=;//de-pulldown
for (i=;i<;i++)
{
CLK=; //>>200ns
DI=dat&0x01; //send a bit to pt6311's data in pin
dat>>=; //lsb first
CLK=;
}
}
u8 ReadByte_PT6311(void)
{
u8 dat,i;
CLK=;
delay_us();
for (i=;i<;i++)
{
CLK=;
dat>>=; //lsb first
if (DO)
dat|=0x80; //catch a bit from pt6311's data out pin
CLK=;
}
return dat;
}
//依次讲解:
ADDR数组:存放了上一篇博文描述的15digit13segment对应ram的地址

我从网上找到的只有pt6312的驱动,他们几乎都用的地址自增模式,
因为本事似乎pt6312的地址就恰好连续的,

如图可知,如果段以及位合适,那么就可以使用地址自增模式。
地址自增:
话说这个datasheet我可能前前后后看了有十来遍(+_+)?
不知到是不是理解的问题,反正我的理解就是如果按照我那个需求,用地址自增有几个字节就无效了
我的实现是固定地址,依次给需要的地址写入内容,故定义了这个数组
下面的font字库是我自己根据相应的位段写好的码,这中间走了弯路,上一篇博文也提到了。
是这样,我抄位段的时候是反着vfd抄的,而我推也按照他来推了,最后显示,完了 上下颠倒了。
咋整???为什么不讲究就这样了?我想用左边的横条显示温度,他满的时候刚好最上面是橙色的,颠倒过来不爽!!
后期也想使用那些图标,总之就是强迫症。当时推这些玩意儿估计用了四十分钟,我用的16位来存的,因为它的位段我几乎都用了。
然后就比对上下,发现似乎不能直接交换bit15到bit0这样。咋整??
硬来!!!
#include "stdio.h" int main()
{
unsigned int font[]={0x7266,0x204,0x630c,0x4836,0x3c4,0x6186,0x6c32,0x1022,0x63c6,0x43c6,//0-9
0x1324,0x4b16,0x6042,0x4a16,0x61c2,0x21c2,0x6742,0x23c4,0x4812,0x604,//a-j
0xc30,0x6040,0x206c,0x264c,0x6246,0x21c6,0x6646,0x25c6,0x6186,0x812,//k-t
0x6244,0x3060,0x3664,0x1428,0x828,0x5022};
unsigned char i,j;
unsigned int ta,tb; for (i=;i<;i++)
{
ta=font[i];tb=; //clr tb|=(ta&0x01)<<;ta>>=;
tb|=(ta&0x01)<<;ta>>=;
tb|=(ta&0x01)<<;ta>>=;
tb|=(ta&0x01)<<;ta>>=;
tb|=(ta&0x01)<<;ta>>=;
tb|=(ta&0x01)<<;ta>>=;
tb|=(ta&0x01)<<;ta>>=;
tb|=(ta&0x01)<<;ta>>=;
tb|=(ta&0x01)<<;ta>>=;
tb|=(ta&0x01)<<;ta>>=;
tb|=(ta&0x01)<<;ta>>=;
tb|=(ta&0x01)<<;ta>>=;
tb|=(ta&0x01)<<;ta>>=;
tb|=(ta&0x01)<<;ta>>=;
tb|=(ta&0x01)<<;ta>>=;
tb|=(ta&0x01);
printf("%#x,",tb);
}
printf("%d %d",'a','b');
return ;
}
转码
我又简单的根据位的分布强行把bit交换,这下好了终于ok了
vfd折腾(二)的更多相关文章
- vfd折腾(一)
从一开始驱动一块翻出来的液晶显示屏就想做一个电子时钟,偶然翻到了vfd(Vacuum Fluorescent Display的缩写,意为真空荧光显示屏). 此后就走上了不归路
- vfd with stm8
2018-01-14 22:50:26 之前写了pt6311的驱动,要做时钟考虑使用stm8做主控,于是乎将之前的驱动移植到stm8上. 顺带熟悉了stm8的操作2333. 上源码: #ifndef ...
- 从此爱上iOS Autolayout
转:从此爱上iOS Autolayout 这篇不是autolayout教程,只是autolayout动员文章和经验之谈,在本文第五节友情链接和推荐中,我将附上足够大家熟练使用autolayout的教程 ...
- 讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(下)- block中任性用self
前言: 在处理完框架内存泄漏的问题后,见上篇:讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(中)- IOS不为人知的Bug 发现业务代码有一个地方的内存没释放,原因很也简单: ...
- C语言及程序设计[套餐]课程主页
课程链接:http://edu.csdn.net/combo/detail/30,提供全部的视频和课件下载. 三部分的课程主页.提供了为每一课时配套的自測.演示样例下载,以及程序阅读.程序填空.实践项 ...
- [转]从此爱上iOS Autolayout
原文地址 这篇不是autolayout教程,只是autolayout动员文章和经验之谈,在本文第五节友情链接和推荐中,我将附上足够大家熟练使用autolayout的教程.这篇文章两个月前就想写下来,但 ...
- Cygwin与minGW
这几天关注了一下它们, 事实上我是不想安装一下vs来编写一些小东西. 本来想写个小exe,于是跑到vs的bin以下把cl与link搞出来,却发现cl还要配置什么的,也不太清楚直接就二个exe与部分dl ...
- FreeBSD jail 折腾记(二)
FreeBSD jail 折腾记(二) 创建jail目录 创建4个 分别是模板 骨架 数据 项目 创建模板目录 mkdir -p /jail/j1 # 然后放入基本目录,上篇说过不再写 创建骨架目录 ...
- ASP.NET Core 折腾笔记二:自己写个完整的Cache缓存类来支持.NET Core
背景: 1:.NET Core 已经没System.Web,也木有了HttpRuntime.Cache,因此,该空间下Cache也木有了. 2:.NET Core 有新的Memory Cache提供, ...
随机推荐
- Mybatis执行BaseExecutor(二)
BaseExecutor是Executor的一个子类,是一个抽象类,其实现了接口Executor的部分方法,并提供了三个抽象方法doUpdate.doFlushStatements和doQuery在他 ...
- LINUX0.11 内核阅读笔记
一.源码目录 图1 二.系统总体流程: 系统从boot开始动作,把内核从启动盘装到正确的位置,进行一些基本的初始化,如检测内存,保护模式相关,建立页目录和内存页表,GDT表,IDT表.然后进入main ...
- 记一个逻辑bug
1 从数据库中找出一个学生能选的毕业设计(毕设的select or not 字段表示本题目是否已经被选 此时就按照其值为n来查询) 2 用户选择某个毕设后,先更新毕设表(select ...
- Linux C 下的大文件操作
这里说的大文件指大小超过4G的文件. 在32位环境下,linux默认打开.读.写超过4G的文件会返回错误.定义如下宏可以突破这个限制,对read/write和fread/fwrite同时有效. 注意它 ...
- WdatePicker()时间控制方式(转载+原创)
控制时间在制定范围内: <input class="wzsrk" name="startDateStr" id="startDateStr ...
- 分布式进阶(十六)Zookeeper入门基础
Zookeeper入门基础 前言 在Zookeeper中,znode是一个跟Unix文件系统路径相似的节点,可以往这个节点存储或获取数据.如果在创建znode时Flag设置为EPHEMERAL,那么当 ...
- Android APP新的“优雅”退出方式--EventBus大显身手
最近在研究eventBus..很多小伙伴不知道他有什么用.. 前篇介绍了EventBus的基本使用 这里简单举一个例子,就是退出APP 转载请注明出处:http://blog.csdn.net/win ...
- [面试算法题]有序列表删除节点-leetcode学习之旅(4)
问题描述 Write a function to delete a node (except the tail) in a singly linked list, given only access ...
- mysql进阶(五)数据表中带OR的多条件查询
MySQL数据表中带OR的多条件查询 OR关键字可以联合多个条件进行查询.使用OR关键字时: 条件 1) 只要符合这几个查询条件的其中一个条件,这样的记录就会被查询出来. 2) 如果不符合这些查询条件 ...
- mongodb系列之---副本集配置与说明
在配置副本集之前,我们先来了解一些关于副本集的知识. 1,副本集的原理 副本集的原理与主从很相似,唯一不同的是,在主节点出现故障的时候,主从配置的从服务器不会自动的变为主服务器,而是要通过手动修改配置 ...