/*******************************************
开发坏境:CCSv5
程序功能:LCD12864显示,可描点绘图,显示汉字,ASCII
程序说明:并行模式,PA2,PA3,PA4分别对应RS,RW,E,PB0-PB7对应数据口
PSB接高电平
编程者:Linchpin
********************************************/
#include <stdint.h>
#include <stdbool.h>
#include <math.h>
#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);
}
本文来自论坛,点击查看完整帖子内容。