#include <ioCC2530.H> #include <string.h> #include <stdio.h> #include "ASCII_CODE_8X16_5X8_VERTICAL.H" #include "Chinese_And_Graphic.H" //====================================================== #define lcd_scl P0_4 //接口定义:lcd_sclk就是LCD的SCL #define lcd_sda P0_5 //接口定义:lcd_sda就是LCD的SDA #define BV(x) (1<<x) #define uchar unsigned char #define uint unsigned int #define ulong unsigned long //延时函数 void Delay_us() //1 us延时 { asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); } void Delay3us() { Delay_us(); Delay_us(); Delay_us(); } void Delay_1ms(void) //1 ms延时 { unsigned int i; for(i=0;i<1000;i++) Delay_us(); } void Delay_ms(uint ms) { for(uint i=0;i<ms;i++) Delay_1ms(); } void start() { lcd_scl = 1; lcd_sda = 1; lcd_sda=0; lcd_scl=0; } void stop() { lcd_scl=0; lcd_sda=0; lcd_sda=1; lcd_scl=1; } //传8位指令或数据到OLED显示模块 void transfer(uchar data1) { unsigned char j; for(j=0;j<8;j++) { lcd_scl=0; if(data1&0x80) lcd_sda=1; else lcd_sda=0; data1<<=1; lcd_scl=1; } lcd_scl=0; Delay3us(); // ACK时间 lcd_scl=1; } //写指令到OLED显示模块 void transfer_command(uchar com) { start(); transfer(0x78); transfer(0x00); transfer(com); stop(); } //写数据到OLED显示模块 void transfer_data(uchar dat) { start(); transfer(0x78); transfer(0x40); transfer(dat); stop(); } //OLED显示模块初始化 void initial_lcd() { Delay_ms(200); transfer_command(0xae); //关显示 transfer_command(0xd5); //晶振频率 transfer_command(0x80); transfer_command(0xa8); //duty设置 transfer_command(0x1f); //duty=1/32 transfer_command(0xd3); //显示偏移 transfer_command(0x00); transfer_command(0xa1); //段重定向设置 transfer_command(0xa6); transfer_command(0x40); //起始行 transfer_command(0xb0); transfer_command(0xd5); transfer_command(0xf0); transfer_command(0x8d); //升压允许 transfer_command(0x14); transfer_command(0x20); //page address mode transfer_command(0x02); transfer_command(0xc8); //行扫描顺序:从上到下 transfer_command(0xa1); //列扫描顺序:从左到右 transfer_command(0xda); //sequential configuration transfer_command(0x02); //**************** transfer_command(0x81); //微调对比度,本指令的0x81不要改动,改下面的值 transfer_command(0xcf); //微调对比度的值,可设置范围0x00~0xff transfer_command(0xd9); //Set Pre-Charge Period transfer_command(0xf1); transfer_command(0xdb); //Set VCOMH Deselect Level transfer_command(0x49); transfer_command(0xaf); //开显示 } void lcd_address(uchar page,uchar column) { column=column-1; //我们平常所说的第1列,在LCD驱动IC里是第0列。所以在这里减去1. page=page-1; transfer_command(0xb0+page); //设置页地址。每页是8行。一个画面的64行被分成8个页。我们平常所说的第1页,在LCD驱动IC里是第0页,所以在这里减去1 transfer_command(((column>>4)&0x0f)+0x10); //设置列地址的高4位 transfer_command(column&0x0f); //设置列地址的低4位 } //全屏清屏 void clear_screen() { unsigned char i,j; for(j=0;j<8;j++) { lcd_address(1+j,1); for(i=0;i<128;i++) { transfer_data(0x00); } } } //full display test void full_display(uchar data1,uchar data2) { int i,j; for(i=0;i<8;i++) { lcd_address(i+1,1); for(j=0;j<64;j++) { transfer_data(data1); transfer_data(data2); } } } //显示128x32点阵的图片 void display_128x32(uchar page,uchar column,uchar *dp) { uint i,j; for(j=0;j<4;j++) { lcd_address(page+j,column); for (i=0;i<128;i++) { transfer_data(*dp); //写数据到LCD,每写完一个8位的数据后列地址自动加1 dp++; } } } //显示单个32x32点阵图像、汉字、生僻字或32x32点阵的其他图标 void display_graphic_32x32(uchar page,uchar column,uchar *dp) { uchar i,j; for(j=0;j<4;j++) { lcd_address(page+j,column); for (i=0;i<32;i++) { transfer_data(*dp); //写数据到LCD,每写完一个8位的数据后列地址自动加1 dp++; } } } //显示单个16x16点阵图像、汉字、生僻字或16x16点阵的其他图标 void display_graphic_16x16(uchar page,uchar column,uchar *dp) { uchar i,j; for(j=0;j<2;j++) { lcd_address(page-1,column); for (i=0;i<16;i++) { transfer_data(*dp); //写数据到LCD,每写完一个8位的数据后列地址自动加1 dp++; } } } //显示单个8x16点阵图像、ASCII, 或8x16点阵的自造字符、其他图标 void display_graphic_8x16(uchar page,uchar column,uchar *dp) { uchar i,j; for(j=0;j<2;j++) { lcd_address(page+j,column); for (i=0;i<8;i++) { transfer_data(*dp); //写数据到LCD,每写完一个8位的数据后列地址自动加1 dp++; } } } //显示8x16的点阵的字符串,括号里的参数分别为(页,列,字符串指针) void display_string_8x16(uint page,uint column,uchar text[]) { uint i=0,j,k,n; if(column>123) { column=1; page+=2; } while(text[i]>0x00) { if((text[i]>=0x20)&&(text[i]<=0x7e)) { j=text[i]-0x20; for(n=0;n<2;n++) { lcd_address(page+n,column); for(k=0;k<8;k++) { transfer_data(ascii_table_8x16[j][k+8*n]); //写数据到LCD,每写完1字节的数据后列地址自动加1 } } i++; column+=8; } else i++; } } //显示5x8的点阵的字符串,括号里的参数分别为(页,列,字符串指针) void display_string_5x8(uint page,uint column,uchar reverse,uchar *text)// 5,1,0 不反显 { // 5,1,1 反显 uint i=0,j,k,disp_data; while(text[i]>0x00) { if((text[i]>=0x20)&&(text[i]<=0x7e)) { j=text[i]-0x20; lcd_address(page,column); for(k=0;k<5;k++) { if(reverse==1) { disp_data=~ascii_table_5x8[j][k]; } else { disp_data=ascii_table_5x8[j][k]; } transfer_data(disp_data); //写数据到LCD,每写完1字节的数据后列地址自动加1 } if(reverse==1) transfer_data(0xff); //写入一列空白列,使得5x8的字符与字符之间有一列间隔,更美观 else transfer_data(0x00); //写入一列空白列,使得5x8的字符与字符之间有一列间隔,更美观 i++; column+=6; if(column>123) { column=1; page++; } } else i++; } } //写入一组16x16点阵的汉字字符串(取模的点阵数据数组中需含有此字) //括号里的参数:(页,列,汉字字符串) void display_string_16x16(uchar page,uchar column,uchar *text) { uchar i,j,k; uint address; j = 0; while(text[j] != '\0') { i = 0; address = 1; while(Chinese_text_16x16[i] > 0x7e) // >0x7f即说明不是ASCII码字符 { if(Chinese_text_16x16[i] == text[j]) { if(Chinese_text_16x16[i + 1] == text[j + 1]) { address = i * 16; break; } } i += 2; } if(column > 113) { column = 0; page += 2; } if(address != 1)// 显示汉字 { for(k=0;k<2;k++) { lcd_address(page+k,column); for(i = 0; i < 16; i++) { transfer_data(Chinese_code_16x16[address]); address++; } } j += 2; } else //显示空白字符 { for(k=0;k<2;k++) { lcd_address(page+k,column); for(i = 0; i < 16; i++) { transfer_data(0x00); } } j++; } column+=16; } } //显示16x16点阵的汉字或者ASCII码8x16点阵的字符混合字符串 //括号里的参数:(页,列,字符串) void disp_string_8x16_16x16(uchar page,uchar column,uchar *text) { uchar temp[3]; uchar i = 0; while(text[i] != '\0') { if(text[i] > 0x7e) { temp[0] = text[i]; temp[1] = text[i + 1]; temp[2] = '\0'; //汉字为两个字节 display_string_16x16(page,column,temp); //显示汉字 column += 16; i += 2; } else { temp[0] = text[i]; temp[1] = '\0'; //字母占一个字节 display_string_8x16(page, column, temp); //显示字母 column += 8; i++; } } } static void port_init( void ) { P0SEL &= ~BV(5); //General-purpose I/O P0DIR |= BV(5); //OutPut P0SEL &= ~BV(4); //General-purpose I/O P0DIR |= BV(4); //OutPut lcd_sda = 1; lcd_scl = 1; } void clock_setup(void) { CLKCONCMD &= ~0x40; //设置系统时钟源为32MHZ晶振 while(CLKCONSTA & 0x40); //等待晶振稳定 CLKCONCMD &= ~0x47; //设置系统主时钟频率为32MHZ } void main(void) { port_init(); initial_lcd(); //初始化 clock_setup(); while(1) { clear_screen(); //清屏 disp_string_8x16_16x16(1,1,"武汉唯众智创科技"); //显示字符串,括号里的参数分别为(PAGE,列,字符串指针) disp_string_8x16_16x16(3,1,"Coming on 123!!"); //显示16x16点阵汉字串或8x16点阵的字符串,括号里的参数分别为(页,列,字符串指针) Delay_ms(1000); } } |