stm3212864并行驱动程序.docx
《stm3212864并行驱动程序.docx》由会员分享,可在线阅读,更多相关《stm3212864并行驱动程序.docx(25页珍藏版)》请在冰点文库上搜索。
stm3212864并行驱动程序
////////////////////////////////////////////////////////////////////////////////
//stm32-12864并行驱动程序
////////////////////////////////////////////////////
#include"delay.h"//必须配合delay.c和delay.h文件使用,所以要包含delay.h。
#include"display12864.h"
f
/**********以下是相关引脚定义。
**************/
//A口的
#defineDisIOGPIOE//定义12864要使用的I/O端口。
#defineDisClkRCC_APB2Periph_GPIOE//定义12864要使用的I/O端口的时钟。
#defineDataGPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7
//定义12864使用的数据引脚。
#defineENGPIO_Pin_10//定义使能端使用的引脚
/*********************************************/
#defineDisIOIO
GPIOE
//定义12864要使用的I/O端口。
#defineDisClkIO
RCC_APB2Periph_GPIOE
//定义12864要使用的I/O端口
的时钟。
#defineRS
#defineRW
GPIO_Pin_9
GPIO_Pin_8
/*光标定位函数定义结束。
*/
#definex10x80
#definex20x88
#definey0x80
GPIO_InitTypeDefGPIOStru;//定义用于定义所以引脚为输出的变量。
/******************************************************************************
*
*函数名:
IOInitOut
*函数描述:
把所有端口初始化为推挽输出模式的函数
*输入参数:
无
*输出结果:
无
*返回值:
无
*******************************************************************************
/
voidIOInitOut(void)
{
//IO组
GPIOStru.GPIO_Mode=GPIO_Mode_Out_PP;//定义所有的引脚为推挽输出的变量初始化。
GPIOStru.GPIO_Speed=GPIO_Speed_50MHz;GPIOStru.GPIO_Pin=Data|EN;
RCC_APB2PeriphClockCmd(DisClkIO,ENABLE);GPIO_Init(DisIO,&GPIOStru);
//IO组
GPIOStru.GPIO_Mode=GPIO_Mode_Out_PP;//定义所有的引脚为推挽输出的变量初始化。
GPIOStru.GPIO_Speed=GPIO_Speed_50MHz;GPIOStru.GPIO_Pin=RS|RW;
RCC_APB2PeriphClockCmd(DisClkIO,ENABLE);GPIO_Init(DisIO,&GPIOStru);
}
/******************************************************************************
*
*函数名:
IOInitIn
*函数描述:
把数据引脚初始化为浮空输入的函
*输入参数:
无
*输出结果:
无
*返回值:
无
*******************************************************************************
/
voidIOInitIn(void)
{
GPIOStru.GPIO_Mode=GPIO_Mode_IN_FLOATING;//定义数据引脚为浮空输入的变量初始化。
GPIOStru.GPIO_Speed=GPIO_Speed_50MHz;GPIOStru.GPIO_Pin=Data;
RCC_APB2PeriphClockCmd(DisClkIO,ENABLE);//把所有端口初始化为输出模式的函数。
GPIO_Init(DisIO,&GPIOStru);
}
/******************************************************************************
*
*函数名:
WaitBusy
*函数描述:
等待12864的忙状态结束的函数
*输入参数:
无
*输出结果:
无
*返回值:
无
*******************************************************************************
/
voidWaitBusy(void)
{
IOInitIn();//把数
据引脚定义为浮空输入
GPIO_ResetBits(DisIOIO,RS);//RS=0
GPIO_SetBits(DisIOIO,RW);//RW=1.
GPIO_SetBits(DisIO,EN);//EN=1.
while(GPIO_ReadInputData(DisIO)&0x0080);//只要位7的值,位7是忙标志位
GPIO_ResetBits(DisIO,EN);//EN=0;
IOInitOut();//把所有引脚定义为输出。
}
/******************************************************************************
*
*函数名:
WriteCmd
*函数描述:
写命令函数
*输入参数:
8位命令
*输出结果:
无
*返回值:
无
*******************************************************************************
/
voidWriteCmd(uint8_tcmd)
{
WaitBusy();
GPIO_ResetBits(DisIOIO,RS);//RS=0.GPIO_ResetBits(DisIOIO,RW);//RW=0.
GPIO_SetBits(DisIO,EN);//EN=1.
DisIO->ODR=((DisIO->ODR&0xff00)|cmd);//此处,只有直接操作寄存器才能
//达到,只改变输出数据寄存器ODR的低8位,其它位
//不变的目的。
因为,只有低8位是数据引脚,
//其它位可能是控制引脚,不能改变。
delay_us
(2);
GPIO_ResetBits(DisIO,EN);//EN=0;
delay_us
(2);
}
/******************************************************************************
*
*函数名:
WriteData
*函数描述:
写数据函数
*输入参数:
8位命令
*输出结果:
无
*返回值:
无
*******************************************************************************
/
voidWriteData(uint8_tdata)
{
WaitBusy();
GPIO_SetBits(DisIOIO,RS);//RS=1.
GPIO_ResetBits(DisIOIO,RW);//RW=0.GPIO_SetBits(DisIO,EN);//EN=1.
DisIO->ODR=((DisIO->ODR&0xff00)|data);//同上。
delay_us
(2);
GPIO_ResetBits(DisIO,EN);//EN=0;
delay_us
(2);
}
/******************************************************************************
*
*函数名:
ReadData
*函数描述:
读IO口状态
*输入参数:
无
*输出结果:
无
*返回值:
8位数据
*******************************************************************************
/
uint8_tReadData(void)
{
uint8_tuc_Content;WaitBusy();
IOInitIn();
delay_ms(10);//注意:
用BCDE组IO口必须这个·延时!
GPIO_SetBits(DisIOIO,RW);//RW=1;读模式
GPIO_SetBits(DisIOIO,RS);//RS=1;数据
GPIO_SetBits(DisIO,EN);//EN=1.使能
delay_us
(2);//延时很重要
//uc_Content=(DisIO->IDR)&0x00ff;uc_Content=GPIO_ReadInputData(DisIO);
GPIO_ResetBits(DisIO,EN);//EN=0.
delay_us
(2);//延时很重要
IOInitOut();
returnuc_Content;
}
/******************************************************************************
*
*函数名:
InitDis
*函数描述:
初始化12864和要用到的STM32的引脚
*输入参数:
无
*输出结果:
无
*返回值:
无
*******************************************************************************
/
voidInitDis(void)
{
IOInitOut();
delay_init(8);//初始化延时函数的微妙计数基数。
WriteCmd(0x30);//选择基本指令集,和,8位数据模式。
delay_ms
(2);
WriteCmd(0x0c);//开显示,无游标,不反白.
delay_ms
(2);
WriteCmd(0x01);//清除显示,并将DDRAM的地址计数器AC设为00H.delay_ms
(2);
WriteCmd(0x06);//设置,外部读写数据后,地址记数器AC会自动加1。
delay_ms
(2);
WriteCmd(0x80);//将DDRAM地址计数器AC设为0.delay_ms
(2);
}
/******************************************************************************
*
*函数名:
DisStr
*函数描述:
显示字符串的函数
*输入参数:
字符串地址
*输出结果:
无
*返回值:
无
*******************************************************************************
/
voidDisStr(uint8_t*s)
{
while(*s!
='\0')
{
WriteData(*s);s++;
delay_ms
(2);
}
}
/******************************************************************************
*
*函数名:
DisInt
*函数描述:
显示整型变量的函数,最多显示16位的整数(只能显示正数)
*输入参数:
16位二进制无符号整型数据
*输出结果:
无
*返回值:
无
*******************************************************************************
/
voidDisInt(uint16_tnum)
{
数倍,
uint8_ttemp[17];uint8_tstr[17];inti=0,j=0;
while(num!
=0)//这里不能用num%10!
=0,如果num是10的整
//例如,100,这样就会出
错,根本就不能进入循环体。
{
temp[i]=(num%10)+0x30;num/=10;
i++;
}
i--;//因为i在退出循环之前还自加了一次,此时,
//指向最后一个存储有用
值的元素的后一个位置。
while(i!
=-1)//因为i=0时,temp[0]还是有用值。
{
str[j]=temp[i];j++;
i--;
}
str[j]='\0';//因为i在退出循环之前还自加了一次,此时,
//指向最后一个存储有用
值的元素的后一个位置。
DisStr(str);
}
/******************************************************************************
*
*函数名:
DisFloat
*函数描述:
显示有n位小数的浮点数,总位数不超过16位
*输入参数:
16位数据
*输出结果:
无
*返回值:
无
*******************************************************************************
/
voidDisFloat(intn,floatfnum)
{
longintnum=fnum*10;uint8_ttemp[17];uint8_tstr[17];
inti=0,j=0;while(num!
=0)
{
temp[i]=(num%10)+0x30;num/=10;
i++;
if(i==n)//4位小数处理完后,加入小数点。
{
}
}i--;
temp[i]='.';i++;
while(i!
=-1)
{
str[j]=temp[i];j++;
i--;
}
str[j]='\0';DisStr(str);
}
/******************************************************************************
*
*函数名:
Locate16
*函数描述:
光标定位函数,第一个参数为行坐标,第二个为列坐标,
起始坐标是1行1列,只能以16个点的宽度为单位移
动
*输入参数:
row----行,col----列
*输出结果:
无
*返回值:
无
*******************************************************************************
/
voidLocate16(introw,intcol)
{
switch(row)
{
case1:
WriteCmd(0x80+col-1);break;case2:
WriteCmd(0x90+col-1);break;case3:
WriteCmd(0x88+col-1);break;case4:
WriteCmd(0x98+col-1);break;
}
}
//显示绘图全屏
/******************************************************************************
*
*函数名:
DisInt
*函数描述:
显示有1位小数的浮点数,总位数不超过16位
*输入参数:
数据
*输出结果:
无
*返回值:
无
*******************************************************************************
/
voidImageWhole(uint8_t*img)
{
uint8_ti,j;for(j=0;j<32;j++)//上半屏
{
for(i=0;i<8;i++)
{
WriteCmd(0x34);
WriteCmd(y+j);//给命令给第几行垂直坐标WriteCmd(x1+i);//给命令给第几列水平坐标WriteCmd(0x30);
WriteData(img[j*16+i*2]);WriteData(img[j*16+i*2+1]);
}
}
for(j=32;j<64;j++)//下半屏
{
for(i=0;i<8;i++)
{
WriteCmd(0x34);//关闭绘图
WriteCmd(y+j-32);//给命令给第几行垂直坐标WriteCmd(x2+i);//给命令给第几列水平坐标WriteCmd(0x30);
WriteData(img[j*16+i*2]);WriteData(img[j*16+i*2+1]);
}
}
WriteCmd(0x36);//打开绘图
}
/******************************************************************************
*
*函数名:
DrawPoint
*函数描述:
画点函数
*输入参数:
xx----行,yy----列(x,y)
*输出结果:
无
*返回值:
无
*******************************************************************************
/
voidDrawPoint(uint8_txx,uint8_tyy)
{
uint8_tx_byte,x_bit;//在横坐标的哪一个字节,哪一个位uint8_ty_byte,y_bit;
uint8_ttmph,tmpl;//定义两个临时变量,用于存放读出来的数据
tmph=0;tmpl=0;
xx=xx&0x7F;yy=yy&0x3F;
x_byte=xx/16;//算出它在哪一个字节(地址)
注意一个地址是16位的
x_bit=xx&0x0F;//算出它在哪一个位
y_byte=yy/32;//y是没在哪个字节这个说法这里只是确定它在上半屏还是下半屏
上半屏1:
下半屏
y_bit=yy&0x1F;//y_bit确定它是在第几行
WriteCmd(0x34);//扩展指令集
WriteCmd(0x34);//绘图显示关闭
WriteCmd(0x80+y_bit);//先写垂直地址(最高位必须为1)
具体参照数据手册
WriteCmd(0x80+x_byte+8*y_byte);//水平坐标
//下半屏的水平坐标起始地址为0x88
//(+8*y_byte)就是用来确定在上半屏还是下半屏
ReadData();//先空读一次
tmph=ReadData();//读高位
tmpl=ReadData();//读低位
WriteCmd(0x80+y_bit);//读操作会改变AC,所以重新设置一次WriteCmd(0x80+x_byte+8*y_byte);
//
//
//0:
//
if(x_bit<8)//如果x_bit位数小于8
{
WriteData(tmph|(0x01<<(7-x_bit)));//写高字节。
因为坐标是从左向右的
//而GDRAM高位在左,底位在右
WriteData(tmpl);//原数据送回
}
else
{
WriteData(tmph);//原数据送回
WriteData(tmpl|(0x01<<(15-x_bit)));
}
WriteCmd(0x36);//打开绘图显示
WriteCmd(0x30);//回到基本指令集,毕竟ST7920
是以字符为主的
}
/******************************************************************************
*
*函数名:
ClearPoint
*函数描述:
清除点函数
*输入参数:
xx----行,yy----列(x,y)
*输出结果:
无
*返回值:
无
*******************************************************************************
/
voidClearPoint(uint8_txx,uint8_tyy)
{
uint8_tx_byte,x_bit;//在横坐标的哪一个字节,哪一个位uint8_ty_byte,y_bit;
uint8_ttmph,tmpl;//定义两个临时变量,用于存放读出来的数据
tmph=0;tmpl=0;
xx=xx&0x7F;yy=yy&0x3F;
x_byte=xx/16;//算出它在哪一个字节(地址)
注意一个地址是16位的
x_bit=xx&0x0F;//算出它在哪一个位
y_byte=yy/32;//y是没在哪个字节这个说法这里只是确定它在上半屏还是