10281|26

164

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

【TIVA C launchpad 学习笔记一】 LCD12864显示,可显示ASCII,中文,描点绘图 [复制链接]

 
/*******************************************
开发坏境:CCSv5
程序功能:LCD12864显示,可描点绘图,显示汉字,ASCII
程序说明:并行模式,PA2,PA3,PA4分别对应RS,RW,E,PB0-PB7对应数据口
       PSB接高电平
编程者:Linchpin
********************************************/
#include
#include
#include
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/fpu.h"
#include "driverlib/sysctl.h"
#include "driverlib/rom.h"
#include "driverlib/pin_map.h"
#include "grlib/grlib.h"
#include "driverlib/gpio.h"
#include "driverlib/adc.h"
#include "inc/hw_gpio.h"
#define uchar unsigned char
#define uint unsigned int

void delay_Nms(uint n);
uchar LCD12864_Busy(void);
void Ini_Lcd(void);
void write_com(uchar com);
void write_dat(uchar dat);
uchar LCD12864_ReadData(void);
void LCD12864_ClearScreen(void);
void drawPoint(unsigned char x,unsigned char y,unsigned char color);
void drawRowLine(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char color);
void drawCollumLine(unsigned char x0,unsigned char y0,unsigned char y1,unsigned char color);
void drawLine(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char color);
void drawsin();
void drawxy_0(void);

uchar const disps[]={"波的频率为:"};

void main(void)
{
        uchar i,j;
    SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL |
    SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);//设置系统时钟为50MHz (400/2/4=50)
    Ini_Lcd();                           //初始化液晶
    LCD12864_ClearScreen();
    for(i=0;i<127;i++)
            for(j=0;j<63;j++)
    {drawPoint(i,j,1);}   //满屏描点
    LCD12864_ClearScreen();
    drawsin();           //画sin函数
    LCD12864_ClearScreen();
    write_com(0x80);
    uchar aa;
        for(aa=0;aa<12;aa++)
        {
                 write_dat(disps[aa]);//显示文字
        }
    while(1);
}

/*******************************************
函数名称:delay_Nms
功    能:延时N个ms的时间
参    数:无
返回值  :无
********************************************/
void delay_Nms(uint n)
{
    uint i = 0;
    for(i = n;i > 0;i--)
            SysCtlDelay(SysCtlClockGet() / 3000);
}

/******************************************************************************
* 函 数 名  : LCD12864_Busy
* 函数功能: 检测LCD是否忙
* 输    入   : 无
* 输    出   : 1或0?1表示不忙?0表示忙?
*******************************************************************************/
uchar LCD12864_Busy(void)
{
    uchar i = 0;
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_2|GPIO_PIN_3,GPIO_PIN_3 );//RS=0,RW=1
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_4, GPIO_PIN_4);   //E=1
    delay_Nms(1);
    while((GPIOPinRead(GPIO_PORTB_BASE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|
                        GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7) & 0x80) == 0x80) //检测读取到的值
    {
        i++;
        if(i > 100)
        {
            GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_4, ~GPIO_PIN_4);   //E=0
            return 0;    //超过等待时间返回0表示失败
        }
    }
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_4, ~GPIO_PIN_4);   //E=0
    return 1;
}
/*******************************************
函数名称:Ini_Lcd
功    能:初始化液晶模块
参    数:无
返回值  :无
********************************************/
void Ini_Lcd(void)
{
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);//使能GPIOA
        GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4);//PA2,3,4设为输出
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);//使能GPIOB
    GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|
                        GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);//PB设为输出
    delay_Nms(15);                     //延时等待液晶完成复位
        GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_4, ~GPIO_PIN_4);   //E=0
        delay_Nms(5);
        write_com(0x30);  /*功能设置:一次送8位数据,基本指令集*/

        delay_Nms(1);
    write_com(0x08);  /*DDRAM地址归位*/
        delay_Nms(1);
        write_com(0x0c);  /*显示设定:开显示,不显示光标,不做当前显示位反白闪动*/
        delay_Nms(1);
        write_com(0x01);  /*清屏,将DDRAM的位址计数器调整为“00H”*/
        delay_Nms(1);
        write_com(0x06);  /*功能设置,点设定:显示字符/光标从左到右移位,DDRAM地址加1*/
        delay_Nms(5);
}

/**************************************************
*名称:void write_com(uchar com)
*功能:向1602写指令
*入口参数:com
*出口参数:无
**************************************************/
void write_com(uchar com)
{
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_2,~GPIO_PIN_2);
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3,~GPIO_PIN_3);//RS=0,RW=0
        GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|
                        GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7, com);    //PB=com
        delay_Nms(1);
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_4, GPIO_PIN_4);   //E=1
    delay_Nms(1);
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_4, ~GPIO_PIN_4);   //E=0
}

/**************************************************
*名称:void write_dat(uchar dat)
*功能:向1602写数据
*入口参数:dat
*出口参数:无
**************************************************/
void write_dat(uchar dat)
{
        GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_2|GPIO_PIN_3,GPIO_PIN_2 );//RS=1,RW=0
        GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|
                                GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7, dat);  //PB=dat
        delay_Nms(1);
        GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_4,GPIO_PIN_4);   //E=1
        delay_Nms(1);
        GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_4, ~GPIO_PIN_4);   //E=0
}

/******************************************************************************
* 函 数 名   : LCD12864_ReadData
* 函数功能 : 读取数据
* 输    入     : 无
* 输    出: 读取到的8位数据
*******************************************************************************/
uchar LCD12864_ReadData(void)
{
    uchar readValue;
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_2,GPIO_PIN_2);
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3,GPIO_PIN_3);//RS=1,RW=1
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_4, ~GPIO_PIN_4);   //E=0
    delay_Nms(1);
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_4, GPIO_PIN_4);   //E=1
    delay_Nms(1);
    GPIOPinTypeGPIOInput(GPIO_PORTB_BASE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|
                           GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);//PB设为输出
    readValue =GPIOPinRead(GPIO_PORTB_BASE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|
                        GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
    GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|
                           GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);//PB设为输出
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_4, ~GPIO_PIN_4);   //E=0
    return readValue;
}

/******************************************************************************
* 函 数 名      : LCD12864_ClearScreen
* 函数功能    : 在画图模式下?LCD12864的01H命令不能清屏?所以要自己写一个清 屏函数
* 输    入       : 无
* 输    出       : 无
*******************************************************************************/
void LCD12864_ClearScreen(void)
{
    uchar i,j;
    write_com(0x34);   //开启拓展指令集
    for(i=0;i<32;i++)     //因为LCD有纵坐标32格所以写三十二次
    {
            write_com(0x80+i);    //先写入纵坐标Y的值
        write_com(0x80);    //再写入横坐标X的值
        for(j=0;j<32;j++)    //横坐标有16位?每位写入两个字节的的数据?也
        {        //就写入32次以为当写入两个字节之后横坐标会自
             write_dat(0x00);   //动加1?所以就不用再次写入地址了。
        }
    }
    write_com(0x36);  //0x36扩展指令里面打开绘图显示
    write_com(0x30);  //恢复基本指令集
}
/***********************************************************
函数名:  drawPoint
函数说明:画点
传入参数:打点位置(x0,y0);color=1,点亮;color=0,擦除
传出参数:无
返回值:  无
**********************************************************/
void drawPoint(unsigned char x,unsigned char y,unsigned char color)
{
        unsigned char row,collum,cbite;
        unsigned char tempH,tempL;
        write_com(0x34);
        write_com(0x36);
        collum=x>>4;
        cbite=x&0x0f;
        if(y<32)
        {row=y;}
        else
        {
                row=y-32;
                collum+=8;
        }
        write_com(0x80+row);
        write_com(0x80+collum);
        LCD12864_ReadData();
        tempH=LCD12864_ReadData();
        tempL=LCD12864_ReadData();
        write_com(0x80+row);
        write_com(0x80+collum);
        if (color)
        {
            if(cbite<8)
            {
                tempH|=(1<<(7-cbite));
                //tempL=(1<<(7-cbite));
                }
                else
                {
                        //tempH=(1<<(15-cbite));
                        tempL|=(1<<(15-cbite));
                }
        }
        else
        {
                if(cbite<8)
                {
                        tempH&=~(1<<(7-cbite));
                        //tempL=(1<<(7-cbite));
                }
                else
                {
                        //tempH=(1<<(15-cbite));
                        tempL&=~(1<<(15-cbite));
                }
        }
        write_dat(tempH);
        write_dat(tempL);
        write_com(0x30);
}
/***********************************************************
函数名:  drawRowLine
函数说明:画水平线
传入参数:(x0,y0),水平线的起点;(x1,y0)水平线的终点,color=1,点亮;color=0,擦除
传出参数:无
返回值:  无
**********************************************************/
void drawRowLine(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char color)
{
        unsigned char  temp;
        if(x0>x1)                                 // 对x0、x1大小进行排列,以便画图
        {
                temp = x1;
                x1 = x0;
                x0 = temp;
        }
        do
        {
                drawPoint(x0, y0, color);        // 逐点显示,描出垂直线
                x0++;
        }
        while(x1>=x0);
}

/***********************************************************
函数名:  drawCollumLine
函数说明:画竖直线
传入参数:(x0,y0),竖直线的起点;(x1,y0)竖直线的终点;color=1,点亮;color=0,擦除
传出参数:无
返回值:  无
************************************************************/
void drawCollumLine(unsigned char x0,unsigned char y0,unsigned char y1,unsigned char color)
{
        unsigned char temp;
        if(y0>y1)
        {
                temp=y0;
                y0=y1;
                y1=temp;
        }
        while (y0<=y1)
        {
                drawPoint(x0,y0,color);
                y0++;
        }
}

/*************************************************************
函数名:  drawLine
函数说明:使用Bresenham法,画任意两点间的直线
传入参数:(x0,y0),竖直线的起点;(x1,y1)竖直线的终点 color=1,点亮;color=0,擦除
传出参数:无
返回值:  无
************************************************************/
void drawLine(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char color)
{
        int   dx;                // 直线x轴差值变量
        int   dy;        // 直线y轴差值变量
        int   dx_sym;        // x轴增长方向,为-1时减值方向,为1时增值方向
        int   dy_sym;        // y轴增长方向,为-1时减值方向,为1时增值方向
        int   dx_2;                // dx*2值变量,用于加快运算速度
        int   dy_2;                // dy*2值变量,用于加快运算速度
        int   di;                // 决策变量
        dx = x1-x0;                // 求取两点之间的差值
        dy = y1-y0;
        if(dx<0)                dx_sym=-1;
        else
        {
                if(dx>0)        dx_sym=1;
                else
                {
                        drawCollumLine(x0,y0,y1,color);
                        return;
                }
        }
        if(dy>0)                        dy_sym=1;
        else
        {
                if(dy<0)        dy_sym=-1;
                else
                {
                        drawRowLine(x0,y0,x1,color);
                        return;
                }
        }
        dx=dx_sym*dx;
        dy=dy_sym*dy;
        dx_2=dx*2;
        dy_2=dy*2;
        if(dx>=dy)
        {
                di=dy_2-dx;
                while(x0!=x1)
                {
                        drawPoint(x0,y0,color);
                        x0+=dx_sym;
                        if(di<0)        di+=dy_2;
                        else        {di+=dy_2-dx_2;y0+=dy_sym;}
                }
                drawPoint(x0,y0,color);
        }
        else
        {
                di=dx_2-dy;
                while(y0!=y1)
                {
                        drawPoint(x0,y0,color);
                        y0+=dy_sym;
                        if(di<0)        di+=dx_2;
                        else                {di+=dx_2-dy_2;x0+=dx_sym;}
                }
                drawPoint(x0,y0,color);
        }
}
/*************************************************************
函数名:  drawsin
函数说明:画sinx函数
传入参数:无
传出参数:无
************************************************************/
void drawsin()
{
            uchar i;
            uchar x0,y0;
            double y;
            drawxy_0();
            for(i=1;i<61;i++)
            {
            x0=64+i;
            y=31*sin(i*3.14159/60.0);
            if((y-(int)y)>=0.5) y=(int)y+1;
            else y=(int)y;
            y0=32-y;
            drawPoint(x0,y0,1);
            }
            for(i=1;i<61;i++)
            {
                x0=64-i;
                y=31*sin(i*3.14159/60.0);
                if((y-(int)y)>=0.5) y=(int)y+1;
                else y=(int)y;
                y0=32+y;
                drawPoint(x0,y0,1);

            }

}

/*************************************************************
函数名:  drawxy_0
函数说明:画坐标轴,包括两条直线和箭头
传入参数:无
传出参数:无
************************************************************/
void drawxy_0(void)
{
        drawRowLine(0,32,127,1);
    drawCollumLine(64,0,63,1);
    drawPoint(63,0,1);
        drawPoint(62,1,1);
        drawPoint(61,2,1);
        drawPoint(65,0,1);
        drawPoint(66,1,1);
        drawPoint(67,2,1);
        drawPoint(127,31,1);
        drawPoint(126,30,1);
        drawPoint(125,29,1);
        drawPoint(127,33,1);
        drawPoint(126,34,1);
        drawPoint(125,35,1);
}


最新回复

多谢楼主,对我帮助很大!  详情 回复 发表于 2018-8-21 23:15
 
点赞 关注(3)

回复
举报

164

帖子

0

TA的资源

一粒金砂(中级)

沙发
 
最近做TI杯写了很多程序,一直没时间分享,楼主有时间会整理起来分享给大家的。
毕竟本人是大二学生,程序中有很多不足之处,希望大家多多指正。

点评

五校联赛难得发了M4这种高级货~ .~... 我也琢磨着把原来的那些东西往上头移植~  详情 回复 发表于 2014-6-17 17:02
 
 

回复

164

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
程序中有任何问题或者有不理解的地方可以问我,每天都会回复的
 
 
 

回复

1185

帖子

1

TA的资源

纯净的硅(高级)

4
 
楼主继续努力。期待后期作品。
 
 
 

回复

130

帖子

13

TA的资源

一粒金砂(高级)

5
 
楼主的程序有的地方值得借鉴,咱在proteus上试了试,
这段程序好像只有顶部可以显示打点图像,其他地方是黑色,
楼主把你在12864硬件上做的实验截图看看在proteus上到底错在哪里。

点评

亲测实际可用的。  详情 回复 发表于 2014-6-17 12:33
 
个人签名good
 
 

回复

164

帖子

0

TA的资源

一粒金砂(中级)

6
 
minjiang 发表于 2014-6-17 11:05
楼主的程序有的地方值得借鉴,咱在proteus上试了试,
这段程序好像只有顶部可以显示打点图像,其他地方是 ...

亲测实际可用的。
 
 
 

回复

18

帖子

0

TA的资源

一粒金砂(中级)

7
 
Linchpin 发表于 2014-6-15 10:35
最近做TI杯写了很多程序,一直没时间分享,楼主有时间会整理起来分享给大家的。
毕竟本人是大二学生,程序 ...

五校联赛难得发了M4这种高级货~ .~... 我也琢磨着把原来的那些东西往上头移植~

 
 
 

回复

12

帖子

0

TA的资源

一粒金砂(中级)

8
 
楼主你好,系统时钟配置为什么是50MHZ?
SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL |
    SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);//设置系统时钟为50MHz (400/2/4=50)
看手册里的系统时钟配置图,感觉是16*(400/2/5)

点评

根据时钟配置图,使用倍频器的话,系统时钟频率=400M/2/SYSDIV  详情 回复 发表于 2014-6-20 23:51
 
 
 

回复

164

帖子

0

TA的资源

一粒金砂(中级)

9
 
三无青年 发表于 2014-6-20 16:39
楼主你好,系统时钟配置为什么是50MHZ?
SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL |
    SYSCTL ...

根据时钟配置图,使用倍频器的话,系统时钟频率=400M/2/SYSDIV
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(中级)

10
 
你好,我按照你所说的接线,将12864的VDD、PSB和A直接接到Launchpad上的VCC,VSS和K接GND,为什么程序烧进去之后没有反应呢?编译的时候也没有错误

点评

VDD和A接VBUS(5V)上。  详情 回复 发表于 2014-7-28 21:32
我和你的情况一样  详情 回复 发表于 2014-7-26 15:29
 
 
 

回复

8

帖子

0

TA的资源

一粒金砂(中级)

11
 
gugehuge 发表于 2014-7-25 21:44
你好,我按照你所说的接线,将12864的VDD、PSB和A直接接到Launchpad上的VCC,VSS和K接GND,为什么程序烧进 ...

我和你的情况一样

点评

VDD和A接VBUS(5V)上。  详情 回复 发表于 2014-7-28 21:32
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(中级)

12
 
给力作品啊
支持多多开源
 
 
 

回复

164

帖子

0

TA的资源

一粒金砂(中级)

13
 
gugehuge 发表于 2014-7-25 21:44
你好,我按照你所说的接线,将12864的VDD、PSB和A直接接到Launchpad上的VCC,VSS和K接GND,为什么程序烧进 ...

VDD和A接VBUS(5V)上。

点评

后来发现IO口不太足够,就选择了引脚较少的OLED,回头我再试试12864能不能用起来,谢谢楼主啦  详情 回复 发表于 2014-7-30 00:23
 
 
 

回复

164

帖子

0

TA的资源

一粒金砂(中级)

14
 

VDD和A接VBUS(5V)上。
 
 
 

回复

5310

帖子

453

TA的资源

五彩晶圆(高级)

15
 
非常不错啊!
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(中级)

16
 
真棒!又开源了
这个值得推广
向楼主学习
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(中级)

17
 
Linchpin 发表于 2014-7-28 21:32
VDD和A接VBUS(5V)上。

后来发现IO口不太足够,就选择了引脚较少的OLED,回头我再试试12864能不能用起来,谢谢楼主啦

点评

IO口不够用可以选择串行模式,可以省下8个IO口  详情 回复 发表于 2014-8-1 09:14
 
 
 

回复

1803

帖子

0

TA的资源

五彩晶圆(高级)

18
 
不错,顶一下,手上有一块 480320 的屏,一值还没来得急驱动,正好可以参考一下。
 
 
 

回复

164

帖子

0

TA的资源

一粒金砂(中级)

19
 
gugehuge 发表于 2014-7-30 00:23
后来发现IO口不太足够,就选择了引脚较少的OLED,回头我再试试12864能不能用起来,谢谢楼主啦

IO口不够用可以选择串行模式,可以省下8个IO口

点评

代码已经测试成功了,先谢谢楼主的分享啦,不过12864如果用串行模式的话,用哪个口作为数据口呢?  详情 回复 发表于 2014-8-1 11:06
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(中级)

20
 
Linchpin 发表于 2014-8-1 09:14
IO口不够用可以选择串行模式,可以省下8个IO口

代码已经测试成功了,先谢谢楼主的分享啦,不过12864如果用串行模式的话,用哪个口作为数据口呢?
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表