找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6414|回复: 3
打印 上一主题 下一主题
收起左侧

stm32开发板自带的玻璃段式液晶屏显示函数--main

[复制链接]
跳转到指定楼层
楼主
ID:73735 发表于 2015-2-19 00:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

void Delay(void) //延时函数
{
unsigned int i;
for(i=0;i<2150;i++);
}
void DelayXms(unsigned int x);
/*****************   延时x毫秒函数 ***********/
void DelayXms(unsigned int x)               
{
unsigned int i,j;
for(i=0;i<x;i++)
for(j=0;j<5150;j++);
}
/********************************************/

void main(void)
{
unsigned char Sec,Min; //保存时钟
unsigned int ms;
Sec=0;
Min=0;
ms=1000;

SystemClockInit();  //系统时钟模块初始化
Usart1Init();
Usart1PutString("System start...\r\n");

LcdInit();

while(1)
{
  //扫描LCD,这里为了演示,使用软件延时调用。
  //实际使用时,可以开一个2ms的定时器,在定时器
  //中断中调用该函数刷新。
  LcdScan();
  DelayXms(2); //延时2ms
  ms+=2; //每次增加2ms
  if(ms>=1000) //秒到达
  {
   ms=0;
   Sec++;
   if(Sec>=60) //分到达
   {
    Sec=0;
    Min++;
    if(Min>=60) //小时到达
    {
     Min=0;
    }
   }
   LcdSetChar((Min/10)+'0',0,0); //分的高位,注意输入参数为字符0,不是数字
   LcdSetChar((Min%10)+'0',1,1); //分的低位(需要显示小数点,最后一个参数为1)
   LcdSetChar((Sec/10)+'0',2,0); //秒的高位
   LcdSetChar((Sec%10)+'0',3,0); //秒的低位
  }
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:73735 发表于 2015-2-19 00:03 | 只看该作者
LCD.C:
#include "gpio.h"
unsigned short int LcdDispBuf[4]; //用来保存显示的段码缓冲
void LcdInit(void)
{
//4个COM口都设置为高阻输入状态
//COM4
//GPIOC_MODE8=0; //输入模式
//GPIOC_CNF8=1;  //高阻(浮空输入)输入模式
//COM3
//GPIOC_MODE9=0; //输入模式
//GPIOC_CNF9=1;  //高阻(浮空输入)输入模式
//COM2
//GPIOC_MODE10=0; //输入模式
//GPIOC_CNF10=1;  //高阻(浮空输入)输入模式
//COM1
//GPIOC_MODE11=0; //输入模式
//GPIOC_CNF11=1;  //高阻(浮空输入)输入模式
//PE口设置为50MHz推挽输出
GPIOE_CRL=0x33333333;
GPIOE_CRH=0x33333333;

//先初始化为无显示
LcdDispBuf[0]=0;
LcdDispBuf[1]=0;
LcdDispBuf[2]=0;
LcdDispBuf[3]=0;
}
//像万利的板子上使用的这种LCD,有4个COM,还有有16个SEG。
//要想某一SEG显示时,需要在对应的SEG和COM之间加上足够的电压,
//但是LCD它不像LED那样,有电压就一直亮的,它只能维持一段
//时间,然后内容就消失了。此时需要将电压反转再加到相应的
//SEG和COM之间。在万利的板子上,COM驱动使用了两个电阻分压,
//输出电压为1/2VCC,当不想让某位显示时,就将它的电压设置
//为1/2VCC(通过设置IO口为高阻态来完成),这样加在对应的
//SEG和COM之间的电压只有1/2VCC,不足以点亮对应的SEG。需要显示
//的,就将COM电压设置为0或者1,这样SEG电压跟COM电压相反的
//段就被点亮了(变黑)。通过定期扫描每个COM,即可稳定的在LCD
//上显示需要的图形了。需要显示字符或者数字时,需要自己将
//对应的图案设计好,需要显示时,发送到相应的SEG和COM上即可。
/*the varitronix LCD digit is:
               A
      --  ----------
    X \/  |\   |I  /|
         F| H  |  J |B
          |  \ | /  |
          --G-- --K--
          |   /| \  |
        E |  L |  N |C
          | /  |M  \|   _
          -----------  | |DP   
              D         -
        PE0  PE1  PE2  PE3  ...................................................... PE15
----------------------------------------------------------------------------------------
|      | S0 | S1 | S2 | S3 | S4 | S5 | S6 | S7 | S8 | S9 | S10| S11| S12| S13| S14| S15|
----------------------------------------------------------------------------------------
| COM1 | 1X | 1I | 1A | 1DP| 2X | 2I | 2A | 2DP| 3X | 3I | 3A | 3DP| 4X | 4I | 4A | 4DP|
----------------------------------------------------------------------------------------
| COM2 | 1F | 1H | 1J | 1B | 2F | 2H | 2J | 2B | 3F | 3H | 3J | 3B | 4F | 4H | 4J | 4B |
----------------------------------------------------------------------------------------
| COM3 | 1E | 1G | 1K | 1C | 2E | 2G | 2K | 2C | 3E | 3G | 3K | 3C | 4E | 4G | 4K | 4C |
----------------------------------------------------------------------------------------
| COM4 | 1L | 1M | 1N | 1D | 2L | 2M | 2N | 2D | 3L | 3M | 3N | 3D | 4L | 4M | 4N | 4D |
----------------------------------------------------------------------------------------
A LCD character coding is based on the following matrix:
{ X , F , E , L  }
{ I , H , G , M  }
{ A , J , K , N  }
{ DP, B , C , D  }
The characher A for example is:
{ 0 , 1 , 1 , 0 }
{ 0 , 0 , 1 , 0 }
{ 1 , 0 , 1 , 0 }
{ 0 , 1 , 1 , 0 }
-------------------
=  4   9   F   0   hex
=> 'A' = 0x49F0  */
const unsigned short int Letter[26]={0x49F0,0x01F8,0x4118,0x08F8,0x4178,0x4170,0x41D8,0x09F0,0x600A,
        0x0888,0x0534,0x0118,0x0F90,0x0B94,0x4998,0x4970,0x499C,0x4974,
        0x41E8,0x6002,0x0998,0x0511,0x299A,0x0605,0x0601,0x4409};
const unsigned short int Number[10]={0x4998,0x0880,0x4878,0x48E8,0x09E0,0x41E8,0x41F8,0x4880,0x49F8,0x49E8};
const unsigned short int Arrow[2]={0x0005,0x0600}; // {Upstair,Downstair}

//根据LCD需要显示的字符设置缓冲区的内容。
//入口参数c为需要显示的字符。
//入口参数p为需要显示的位置,从左往右依次为0,1,2,3。
//入口参数dot为是否需要显示小数点和单引号,1只显示小数点,
//2只显示单引号,3为小数点和单引号同时显示
void LcdSetChar(unsigned char c, unsigned char p, unsigned char dot)
{
//定义一个Temp变量来保存查表的结果
unsigned short int Temp;

if(p>3)return;

if((c>='A')&&(c<='Z'))  //A~Z之间的字符
{
  Temp=Letter[c-'A'];
}
else if((c>='0')&&(c<='9'))  //0~9之间的数
{
  Temp=Number[c-'0'];
}
else if(c=='\'') //单引号
{
  Temp=0x1000;
}
else if(c=='.') //小数点
{
  Temp=0x8000;
}
else //暂时不支持其它字符显示
{
  Temp=0;
}
//如果需要显示小数点
if(dot==1)Temp|=0x8000;
if(dot==2)Temp|=0x1000;
if(dot==3)Temp|=0x9000;
//根据不同的位置,设置显示缓冲区中的值
//在这里,并不是每个COM都刚好对应着LCD
//上的一个字符位置,而是每个COM都同时
//控制着4个字符中的4个SEG,因此需要修改
//某个字符位置的显示,就必须将显示缓冲
//区中的每个变量中对应的4位进行修改。
//将COM1选中时显示的SEG中的对应4位先清0
LcdDispBuf[0]&=~((0xF)<<(p*4));
//然后再将需要显示的内容写入
LcdDispBuf[0]|=(((Temp>>12)&0xF)<<(p*4));
//将COM1选中时显示的SEG中的对应4位先清0
LcdDispBuf[1]&=~((0xF)<<(p*4));
//然后再将需要显示的内容写入
LcdDispBuf[1]|=(((Temp>>8)&0xF)<<(p*4));
//将COM1选中时显示的SEG中的对应4位先清0
LcdDispBuf[2]&=~((0xF)<<(p*4));
//然后再将需要显示的内容写入
LcdDispBuf[2]|=(((Temp>>4)&0xF)<<(p*4));
//将COM1选中时显示的SEG中的对应4位先清0
LcdDispBuf[3]&=~((0xF)<<(p*4));
//然后再将需要显示的内容写入
LcdDispBuf[3]|=(((Temp)&0xF)<<(p*4));
}
//每隔一段时间要调用一次该函数,例如2ms
//可以在一个定时器中调用该函数来定期刷新
//这里为了演示程序,使用软件延时的方法
void LcdScan(void)
{
static unsigned int i=1;
static unsigned int Off=0;

if(Off==1)
{
  Off=0;
  //先将4个COM都设置为高阻状态
  GPIOC_MODE8=0; //输入模式
  GPIOC_CNF8=1;  //高阻输入模式
  GPIOC_MODE9=0; //输入模式
  GPIOC_CNF9=1;  //高阻输入模式
  GPIOC_MODE10=0; //输入模式
  GPIOC_CNF10=1;  //高阻输入模式
  GPIOC_MODE11=0; //输入模式
  GPIOC_CNF11=1;  //高阻输入模式
  
  //然后将所有SEG设置为低电平
  GPIOE_ODR=0;
  
  //再将所有COM设置为低电平
  GPIOC_CLR=(1<<8)|(1<<9)|(1<<10)|(1<<11);
  GPIOC_MODE8=3; //50M输出模式
  GPIOC_CNF8=0;  //推挽模式
  GPIOC_MODE9=3; //50M输出模式
  GPIOC_CNF9=0;  //推挽模式
  GPIOC_MODE10=3; //50M输出模式
  GPIOC_CNF10=0;  //推挽模式
  GPIOC_MODE11=3; //50M输出模式
  GPIOC_CNF11=0;  //推挽模式
  return;
}
else
{
  Off=1;
  //先将4个COM都设置为高阻状态
  GPIOC_MODE8=0; //输入模式
  GPIOC_CNF8=1;  //高阻输入模式
  GPIOC_MODE9=0; //输入模式
  GPIOC_CNF9=1;  //高阻输入模式
  GPIOC_MODE10=0; //输入模式
  GPIOC_CNF10=1;  //高阻输入模式
  GPIOC_MODE11=0; //输入模式
  GPIOC_CNF11=1;  //高阻输入模式  
}
switch(i)
{
  case 1:
  //COM4的前半个周期
  GPIOE_ODR=LcdDispBuf[3]; //将SEG码输出   
  GPIOC_CLR=1<<8; //COM4输出低电平
  GPIOC_CNF8=0;  //推挽输出
  GPIOC_MODE8=3; //50MHz输出模式
   break;
   
  case 2:
  //COM4的后半个周期
  GPIOE_ODR=~LcdDispBuf[3]; //将SEG码取反   
  GPIOC_SET=1<<8; //COM4输出高电平
  GPIOC_CNF8=0;  //推挽输出
  GPIOC_MODE8=3; //50MHz输出模式
   break;
   
  case 3:
  //COM3的前半个周期
  GPIOE_ODR=LcdDispBuf[2]; //将SEG码输出   
  GPIOC_CLR=1<<9; //COM3输出低电平  
  GPIOC_CNF9=0;  //推挽输出   
  GPIOC_MODE9=3; //50MHz输出模式
   break;
   
  case 4:
  //COM3的后半个周期
  GPIOE_ODR=~LcdDispBuf[2]; //将SEG码取反   
  GPIOC_SET=1<<9; //COM3输出高电平  
  GPIOC_CNF9=0;  //推挽输出   
  GPIOC_MODE9=3; //50MHz输出模式
   break;
   
  case 5:
  //COM2的前半个周期
  GPIOE_ODR=LcdDispBuf[1]; //将SEG码输出   
  GPIOC_CLR=1<<10; //COM2输出低电平  
  GPIOC_CNF10=0;  //推挽输出   
  GPIOC_MODE10=3; //50MHz输出模式
   break;
   
  case 6:
  //COM2的后半个周期
  GPIOE_ODR=~LcdDispBuf[1]; //将SEG码取反   
  GPIOC_SET=1<<10; //COM2输出高电平  
  GPIOC_CNF10=0;  //推挽输出   
  GPIOC_MODE10=3; //50MHz输出模式
   break;
   
  case 7:
  //COM1的前半个周期
  GPIOE_ODR=LcdDispBuf[0]; //将SEG码输出   
  GPIOC_CLR=1<<11; //COM1输出低电平  
  GPIOC_CNF11=0;  //推挽输出   
  GPIOC_MODE11=3; //50MHz输出模式
   break;
   
  case 8:
  //COM1的后半个周期
  GPIOE_ODR=~LcdDispBuf[0]; //将SEG码取反   
  GPIOC_SET=1<<11; //COM1输出高电平  
  GPIOC_CNF11=0;  //推挽输出
  GPIOC_MODE11=3; //50MHz输出模式
  i=0;
   break;
   
  default :
  i=0;
}
//切换到下一状态
i++;
}
LCD.h:
#ifndef __LCD_H__
#define __LCD_H__
void LcdScan(void);
void LcdInit(void);
void LcdSetChar(unsigned char c, unsigned char p, unsigned char dot);
extern unsigned short int LcdDispBuf[4]; //用来保存显示的段码缓冲
#endif

回复

使用道具 举报

板凳
ID:112557 发表于 2016-4-6 19:06 | 只看该作者
GPIO.H呢
回复

使用道具 举报

地板
ID:112557 发表于 2016-4-6 19:59 | 只看该作者
兄弟 快点回复呀
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表