|
发表于 2009-4-29 22:33:29
|
显示全部楼层
最近也做了个OLED的温度计,方案是
ZLG Easy ARM1138+18B20+2.4OLED双色屏+LT3465
本来想等CP2102的USB转串口做完,可以在电脑上记录分析温度以后才传方案,
现在既然楼主先贴了,那我也来凑凑热闹吧。
(原文件名:Photo_0001.jpg)
(原文件名:Photo_0003.jpg)
几个比较关键的代码:
OLED屏幕定义,完全根据ZLG的TFT驱动来搞,没有更改,RS接A0的位置,其他都能对上号。
/*********************************************************************************************************
硬件相关接口定义
*********************************************************************************************************/
#define LCD_PERI SYSCTL_PERIPH_GPIOA | SYSCTL_PERIPH_GPIOB
#define LCD_RS_BASE GPIO_PORTB_BASE /* RS - PB0 */
#define LCD_RS_PIN GPIO_PIN_0
#define LCD_CS_BASE GPIO_PORTB_BASE /* CS - PB1 */
#define LCD_CS_PIN GPIO_PIN_1
#define LCD_WR_BASE GPIO_PORTB_BASE /* WR - PB2 */
#define LCD_WR_PIN GPIO_PIN_2
#define LCD_RD_BASE GPIO_PORTB_BASE /* RD - PB3 */
#define LCD_RD_PIN GPIO_PIN_3
#define LCD_RST_BASE GPIO_PORTB_BASE /* RST - PB4 */
#define LCD_RST_PIN GPIO_PIN_4
#define DATA_PORT_BASE GPIO_PORTA_BASE /* DATA[7:0] - PA[7:0] */
#define DATA_PORT_PIN 0xFF
/*********************************************************************************************************
硬件相关的定义
*********************************************************************************************************/
#define LCD_CS_BASE_PIN LCD_CS_BASE,LCD_CS_PIN
#define LCD_WR_BASE_PIN LCD_WR_BASE,LCD_WR_PIN
#define LCD_RS_BASE_PIN LCD_RS_BASE,LCD_RS_PIN
#define LCD_RD_BASE_PIN LCD_RD_BASE,LCD_RD_PIN
#define LCD_RST_BASE_PIN LCD_RST_BASE,LCD_RST_PIN
#define DATA_PORT_BASE_PIN DATA_PORT_BASE,DATA_PORT_PIN
/*********************************************************************************************************
硬件相关的位操作定义
*********************************************************************************************************/
#define LCD_RS HWREG(LCD_RS_BASE + (GPIO_O_DATA + (LCD_RS_PIN << 2)))
#define LCD_CS HWREG(LCD_CS_BASE + (GPIO_O_DATA + (LCD_CS_PIN << 2)))
#define LCD_WR HWREG(LCD_WR_BASE + (GPIO_O_DATA + (LCD_WR_PIN << 2)))
#define LCD_RD HWREG(LCD_RD_BASE + (GPIO_O_DATA + (LCD_RD_PIN << 2)))
#define LCD_RST HWREG(LCD_RST_BASE + (GPIO_O_DATA + (LCD_RST_PIN << 2)))
#define DATA_PORT HWREG(DATA_PORT_BASE + (GPIO_O_DATA + (DATA_PORT_PIN << 2)))
#define DATA_PROT_INPUT_SET() HWREG(DATA_PORT_BASE + GPIO_O_DIR) = 0 /* 设置数据口为输入方向 */
#define DATA_PROT_OUTPUT_SET() HWREG(DATA_PORT_BASE + GPIO_O_DIR) = 0xFF
/* 设置数据口为输出方向 */
/*********************************************************************************************************
** 函数名称: __writeData8
** 功能描述: (向当前地址的寄存器)写8位数据
** 输 入: ucData 要写入液晶的8位数据
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
** 返 回:无
** 作 者:
** 日 期:
**------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**------------------------------------------------------------------------------------------------------
*********************************************************************************************************/
void __writeData8(INT8U ucData) /* 写8位数据函数 */
{
LCD_RS = 0xFF; /* 拉高RS */
LCD_CS = 0x00; /* 拉低CS */
LCD_WR = 0x00; /* 拉低WR */
DATA_PORT = ucData; /* 写数据 */
LCD_WR = 0xFF; /* 拉高WR */
LCD_CS = 0xFF; /* 拉高CS */
LCD_RS = 0x00; /* 拉低RS */
}
/*********************************************************************************************************
** 函数名称: __writeCommand
** 功能描述: 写命令函数
** 输 入: unsigned char data 输入的命令
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
** 返 回:无
** 作 者:
** 日 期:
**------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**------------------------------------------------------------------------------------------------------
*********************************************************************************************************/
void __writeCommand(unsigned char data)
{
// 写8位地址
LCD_RS = 0x00; /* 拉低RS */
LCD_CS = 0x00;
LCD_WR = 0x00;
DATA_PORT = data;
LCD_WR = 0xFF;
LCD_CS = 0xFF;
}
/*********************************************************************************************************
** 函数名称: tftLcdInit
** 功能描述: 液晶初始化
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块: __writeCommand()、
** 返 回:无
** 作 者:
** 日 期:
**------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**------------------------------------------------------------------------------------------------------
*********************************************************************************************************/
void tftLcdInit(void) /* 初始化函数 */
{
SysCtlPeriEnable(LCD_PERI); /* 使能相应的GPIO */
GPIOPinTypeOut(LCD_CS_BASE_PIN); /* 设置相应的控制管脚为输出 */
GPIOPinTypeOut(LCD_WR_BASE_PIN); /* 设置相应的控制管脚为输出 */
GPIOPinTypeOut(LCD_RS_BASE_PIN); /* 设置相应的控制管脚为输出 */
GPIOPinTypeOut(LCD_RD_BASE_PIN); /* 设置相应的控制管脚为输出 */
GPIOPinTypeOut(LCD_RST_BASE_PIN); /* 设置相应的控制管脚为输出 */
GPIOPinTypeOut(DATA_PORT_BASE_PIN); /* 设置相应的数据管脚为输出 */
LCD_RS = 0xFF; /* 初始化输出为高电平 */
LCD_CS = 0xFF; /* 初始化输出为高电平 */
LCD_WR = 0xFF;; /* 初始化输出为高电平 */
LCD_RD = 0xFF; /* 初始化输出为高电平 */
LCD_RST = 0xFF; /* 初始化输出为高电平 */
DATA_PORT = 0xFF;
LCD_RST = 0x00; /* 拉低复位引脚 */
SysCtlDelay(10 * SysCtlClockGet() / 3000);
LCD_RST = 0xFF; /* 拉高复位引脚 */
SysCtlDelay(10 * SysCtlClockGet() / 3000);
//initializing funciton 1
__writeCommand(0xAE); //display off
__writeCommand(0x02); //set lower column address
__writeCommand(0x10); //set higher column address
__writeCommand(0x40); //set display start line
__writeCommand(0xB0); //set page address
__writeCommand(0x81); //contract control
__writeCommand(0x80); //128
__writeCommand(0xA1); //set segment remap
__writeCommand(0xA4); //normal display
__writeCommand(0xA6); //normal / reverse
__writeCommand(0xA8); //multiplex ratio
__writeCommand(0x3F); //duty = 1/64
__writeCommand(0xC8); //Com scan direction
__writeCommand(0xD3); //set display offset
__writeCommand(0x00);
__writeCommand(0xD5); //set osc division
__writeCommand(0x00);
__writeCommand(0xD8); //set area color mode off
__writeCommand(0x05);
__writeCommand(0xDA); // set COM pins
__writeCommand(0x12);
__writeCommand(0xDB); //
__writeCommand(0x40);
__writeCommand(0xAF); //display ON
}
这个是从原版的OLED驱动改过来的,hdat和ldat没有用,只是让它黑屏
void fill(unsigned char hdat,unsigned char ldat)
{
unsigned char x,y;
for(y=0;y<8;y++) /*8行
{
__writeCommand(0x02); /*set lower column address ' 04*/
__writeCommand(0x10); /*set higher column address ' 12*/
__writeCommand(0xB0+y); /*set page address*/
for(x=0;x<64;x++)
{
__writeData8(0);
__writeData8(0);
}
}
}
写半角西文
void disc(unsigned char X,unsigned char Y,unsigned char c)
{
unsigned m,n;
for(n=0;n<3;n++)
{
__writeCommand(0xB0|(n+Y)); /*set page address*/
__writeCommand(0x00+X%16); // Set Lower Column Start Address for Page Addressing Mode
// Default => 0x00
__writeCommand(0x10+X/16); // Set Higher Column Start Address for Page Addressing Mode
// Default => 0x10
for(m=0;m<12;m++)
__writeData8(dig[m+c*36+n*12]);
}
}
写汉字
void dishz(unsigned char X,unsigned char Y,unsigned char h)
{
unsigned m,n;
for(n=0;n<3;n++)
{
__writeCommand(0xB0|(n+Y)); /*set page address*/
__writeCommand(0x00+X%16); // Set Lower Column Start Address for Page Addressing Mode
// Default => 0x00
__writeCommand(0x10+X/16); // Set Higher Column Start Address for Page Addressing Mode
// Default => 0x10
for(m=0;m<24;m++)
__writeData8(hz[m+h*72+n*24]);
}
}
/*********************************************************************************************************
** 定时器的中断服务函数
** 每毫秒中断一次
*********************************************************************************************************/
void Timer0A_ISR(void)
{
TimerIntClear(T0_A_INT_TIMEOUT); /* 清除定时器超时中断,重要! */
if (GulDelayMs < 0xFFFFFFFFUL) {
GulDelayMs++; /* 在delayMs()函数中清零,用于 */
/* 精确延时 */
}
}
/*********************************************************************************************************
精确延时函数 GulDelayMs由定时器中断每1ms加1
*********************************************************************************************************/
void delayMs(unsigned long ulVal)
{
GulDelayMs = 0;
while (GulDelayMs < ulVal);
}
/*********************************************************************************************************
定时器初始化
*********************************************************************************************************/
void timer0Init(void)
{
IntRegister(INT_TIMER0A, Timer0A_ISR); /* 注册中断服务函数 */
SysCtlPeriEnable(SYSCTL_PERIPH_TIMER0); /* 使能定时器模块 */
TimerConfigure(T0_CFG_32_PER); /* 配置定时器为32位周期定时器 */
TimerLoadSet(T0_A , GulSysClock/1000); /* 设置定时器初值 */
TimerIntEnable(T0_A_INT_TIMEOUT); /* 使能定时器超时中断 */
IntEnable(INT_TIMER0A); /* 使能定时器中断 */
IntMasterEnable(); /* 使能处理器中断 */
GulDelayMs = 0;
TimerEnable(T0_A); /* 使能定时器计数 */
}
/*********************************************************************************************************
** 定时器的中断服务函数
** 每微秒中断一次
*********************************************************************************************************/
void Timer1A_ISR(void)
{
TimerIntClear(T1_A_INT_TIMEOUT); /* 清除定时器超时中断,重要! */
if (GulDelayUs < 0xFFFFFFFFUL) {
GulDelayUs++; /* 在delayUs()函数中清零,用于 */
/* 精确延时 */
}
}
/*********************************************************************************************************
精确延时函数 GulDelayMs由定时器中断每1ms加1
*********************************************************************************************************/
void delayUs(unsigned long ulVal)
{
GulDelayUs = 0;
IntEnable(INT_TIMER1A);
while (GulDelayUs < ulVal);
IntDisable(INT_TIMER1A);
}
/*********************************************************************************************************
定1时器初始化
*********************************************************************************************************/
void timer1Init(void)
{
IntRegister(INT_TIMER1A, Timer1A_ISR); /* 注册中断服务函数 */
SysCtlPeriEnable(SYSCTL_PERIPH_TIMER1); /* 使能定时器模块 */
TimerConfigure(T1_CFG_32_PER); /* 配置定时器为32位周期定时器 */
TimerLoadSet(T1_A , GulSysClock/1000000); /* 设置定时器初值 */
TimerIntEnable(T1_A_INT_TIMEOUT); /* 使能定时器超时中断 */
// IntEnable(INT_TIMER1A); /* 使能定时器中断 */
TimerEnable(T1_A); /* 使能定时器计数 */
}
/*********************************************************************************************************
** 18B02初始化
** DQ:D2
*********************************************************************************************************/
unsigned char T18B02Int(void)
{
unsigned char DQdata;
DQoutput(DQ); // 设置DQ脚为输出
DQhigh(DQ); //拉高总线
delayUs(5);
DQlow(DQ); //拉底总线
delayUs(600); //延时大于480us
DQinput(DQ);
delayUs(40);
DQdata=GPIOPinRead(DQ); //读取DQ值
delayUs(500); //延时20us
return(DQdata);
}
/**********************************************************************
读DS18B20一个字节
**********************************************************************/
unsigned char read_bit(void)
{
static unsigned char dataDQ;
DQoutput(DQ);
delayUs(2);
DQhigh(DQ);
delayUs(2);
DQlow(DQ);
delayUs(5);
DQinput(DQ);
dataDQ=GPIOPinRead(DQ);
delayUs(60);
return(dataDQ);
}
/**********************************************************************
写DS18B20一个字节
**********************************************************************/
void write_bit(unsigned char bitval)
{
DQoutput(DQ); // 设置DQ脚为输出
delayUs(2);
DQhigh(DQ);
delayUs(2);
DQlow(DQ); //拉底总线
delayUs(5);
if (bitval==1)
{
DQhigh(DQ);
}
delayUs(55);
}
/**********************************************************************
读DS18B20一个字节
**********************************************************************/
unsigned char readByteDS18B20(void)
{
unsigned char i;
unsigned char j;
unsigned char value=0;
for (i=0;i<8;i++)
{
j=read_bit(); //调读位函数
if (j) //如果是 1 置1
{
value|=(0x01<<i); //先读低位,再读高位
delayUs(3);
}
} //否则置 0
return(value);
}
/**********************************************************************
写DS18B20一个字节
**********************************************************************/
void writeByteDS18B20(unsigned char val)
{
unsigned char i;
unsigned char temp;
for (i=0;i<8;i++)
{
temp=val>>i;
temp&=0x01;
write_bit(temp); //调写位函数
}
delayUs(3);
}
/**********************************************************************
读DS18B20温度
**********************************************************************/
unsigned int readTempDS18B20(void)
{
unsigned char tempL,tempH;
unsigned int x;
while(T18B02Int());
writeByteDS18B20(0xcc); //跳过ROM
writeByteDS18B20(0x44); //启动温度转换
DQinput(DQ);
while(!GPIOPinRead(DQ));
while(T18B02Int());
delayUs(5);
writeByteDS18B20(0xcc); //跳过ROM
writeByteDS18B20(0xbe); //读数据
tempL=readByteDS18B20();
tempH=readByteDS18B20();
x=(tempH<<8)|tempL;
return(x);
}
/**********************************************************************
读DS18B20 ID
**********************************************************************/
unsigned int readIDDS18B20(void)
{
unsigned char tempL,tempH;
unsigned int x;
while(T18B02Int());
writeByteDS18B20(0x33); //读ID
tempL=readByteDS18B20();
tempH=readByteDS18B20();
x=(tempH<<8)|tempL;
return(x);
}
这条程序很眼熟吧,是在论坛的一位高手的程序挖过来的。
/************************************************************************************
把浮点数拆开存储指针型数据
输入浮点数,方式0:设定值,1:检测值
************************************************************************************/
void chai(float x,unsigned char y)
{
uint i;
for(i = 0;i < 7;i ++)
GOUT = 0;
if(y == 0)
{
i = x / 10;
if(i == 0)
GOUT[0] = ' ';
else
GOUT[0] = i + '0';
GOUT[1] = (int)x % 10 + '0';
x = x * 10;
GOUT[3] = (int)x % 10 + '0';
x = x * 10;
if(((int)x % 10) >= 5 )// 防止后面大于4的数被舍去
{GOUT[3] = GOUT[3] + 1;}
else
{;}
GOUT[4] = ' ';
GOUT[5] = ' ';
}
else
{
i = x / 10;
if(i == 0)
GOUT[0] = ' ';
else
GOUT[0] = i + '0';
GOUT[1] = (int)x % 10 + '0';
x = x * 10;
GOUT[3] = (int)x % 10 + '0';
x = x * 10;
GOUT[4] = (int)x % 10 + '0';
x = (x * 10);
GOUT[5] = (unsigned int)x % 10 + '0';
}
GOUT[2] = '.';
GOUT[6] = '\0';
}
int main(void)
{
unsigned char n;
unsigned int Tem=0x00000000;
float Temperature=0.0;
jtagWait(); /* 防止JTAG失效,重要! */
GulSysClock = clockInit(); /* 获取系统时钟,单位:Hz */
timer0Init(); /* 定时器初始化 */
timer1Init();
tftLcdInit();
fill(255,255);
dishz(0,5,0);
dishz(24,5,1);
disc(55,5,0);
disc(67,5,0);
disc(79,5,10);
disc(91,5,0);
dishz(103,5,2);
ledInit();
SysCtlPeriEnable(DQ_PERI);
while (1) {
Tem=readTempDS18B20();
Temperature=0.0;
if(Tem&0x0001)
{
Temperature+=0.0625;
}
if(Tem&0x0002)
{
Temperature+=0.125;
}
if(Tem&0x0004)
{
Temperature+=0.25;
}
if(Tem&0x0008)
{
Temperature+=0.5;
}
if(Tem&0x0010)
{
Temperature+=1;
}
if(Tem&0x0020)
{
Temperature+=2;
}
if(Tem&0x0040)
{
Temperature+=4;
}
if(Tem&0x0080)
{
Temperature+=8;
}
if(Tem&0x0100)
{
Temperature+=16;
}
if(Tem&0x0200)
{
Temperature+=32;
}
if(Tem&0x0400)
{
Temperature+=64;
}
if(Tem&0x0800)
{
Temperature*=(-1);
}
chai(Temperature,1);
disc(55,5,GOUT[0]-'0');
disc(67,5,GOUT[1]-'0');
disc(91,5,GOUT[3]-'0');
}
} |
|