STM8下驱动192*64 LCD
以下代码驱动192*64的LCD已经成功地在STM8下运行,速度有点慢,还请大家改进// 头文件: LCD_19264.H
#ifndef _LCD19264_H
#define _LCD19264_H
#include "stm8s.h"
// DB0~DB7
#define LCD_DATA_PORT (GPIOB)
#define LCD_DATA_PIN (GPIO_PIN_ALL)
// E, RS, RW
#define LCD_CONTROL_PORT (GPIOA)
#define LCD_E_PIN (GPIO_PIN_4)
#define LCD_RW_PIN (GPIO_PIN_5)
#define LCD_RS_PIN (GPIO_PIN_6)
// CSA, CSB
#define LCD_CS_PORT (GPIOG)
#define LCD_CSA_PIN (GPIO_PIN_0)
#define LCD_CSB_PIN (GPIO_PIN_1)
#define LCD_RES_PORT (GPIOE)
#define LCD_RES_PIN (GPIO_PIN_0)
#define LCD_LEFT ((u8)1)
#define LCD_MID ((u8)2)
#define LCD_RIGHT ((u8)3)
#define LCD_DISPLAY_ON((u8)0x3f)
#define LCD_DISPLAY_OFF ((u8)0x3e)
#define LCD_YADDR_BASE((u8)0x40)
#define LCD_XPAGE_BASE((u8)0xB8)
#define LCD_START_LINE((u8)0xC0)
typedef enum _DrawMode{
LCD_CLEAR,
LCD_NOT,
LCD_SET
}DrawMode;
void LCD_Init(void);
void LCD_WriteCommand(u8 cmd, u8 ChipSel);
void LCD_WriteData(u8 Data, u8 ChipSel);
void LCD_BufferDrawPixel(u8 x, u8 y, DrawMode mode);
void LCD_BufferDrawLine(u8 x1, u8 y1, u8 x2, u8 y2, DrawMode mode);
void LCD_BufferToLCD(void);
#endif
// C语言文件LCD_19264.C
#include "lcd_19264.h"
#include "delay.h"
#define LCD_CSA_H() (GPIO_WriteHigh(LCD_CS_PORT, LCD_CSA_PIN))
#define LCD_CSA_L() (GPIO_WriteLow(LCD_CS_PORT, LCD_CSA_PIN))
#define LCD_CSB_H() (GPIO_WriteHigh(LCD_CS_PORT, LCD_CSB_PIN))
#define LCD_CSB_L() (GPIO_WriteLow(LCD_CS_PORT, LCD_CSB_PIN))
#define LCD_E_H() (GPIO_WriteHigh(LCD_CONTROL_PORT, LCD_E_PIN))
#define LCD_E_L() (GPIO_WriteLow(LCD_CONTROL_PORT, LCD_E_PIN))
#define LCD_RS_H() (GPIO_WriteHigh(LCD_CONTROL_PORT, LCD_RS_PIN))
#define LCD_RS_L() (GPIO_WriteLow(LCD_CONTROL_PORT, LCD_RS_PIN))
#define LCD_RW_H() (GPIO_WriteHigh(LCD_CONTROL_PORT, LCD_RW_PIN))
#define LCD_RW_L() (GPIO_WriteLow(LCD_CONTROL_PORT, LCD_RW_PIN))
#define LCD_DATA_INPUT_MODE() (GPIO_Init(LCD_DATA_PORT, LCD_DATA_PIN, GPIO_MODE_IN_FL_NO_IT))
#define LCD_DATA_OUTPUT_MODE()(GPIO_Init(LCD_DATA_PORT, LCD_DATA_PIN, GPIO_MODE_OUT_PP_HIGH_FAST))
#define LCD_SET_DATA(x) (GPIO_Write(LCD_DATA_PORT, x))
#define LCD_READ_DATA() (GPIO_ReadInputData(LCD_DATA_PORT))
@near static u8 DisplayBuffer;
void LCD_WriteCommand(u8 cmd, u8 ChipSel)
{
LCD_E_L();
LCD_RW_L();
if( ChipSel == LCD_LEFT )
{
LCD_CSB_L();
LCD_CSA_L();
}
else if( ChipSel == LCD_MID )
{
// CSB_CSA
LCD_CSB_L();
LCD_CSA_H();
}
else
{
LCD_CSB_H();
LCD_CSA_L();
}
LCD_RS_L(); // Command signal
//delay_us(1);
LCD_E_H();
LCD_SET_DATA(cmd);
delay_us(1);
LCD_E_L();
LCD_RW_H();
LCD_CSB_H();
LCD_CSA_H();
LCD_E_H();
}
void LCD_WriteData(u8 Data, u8 ChipSel)
{
LCD_E_L();
LCD_RW_L();
if( ChipSel == LCD_LEFT )
{
LCD_CSB_L();
LCD_CSA_L();
}
else if( ChipSel == LCD_MID )
{
// CSB_CSA
LCD_CSB_L();
LCD_CSA_H();
}
else
{
LCD_CSB_H();
LCD_CSA_L();
}
LCD_RS_H(); // Data signal
//delay_us(1);
LCD_E_H();
LCD_SET_DATA(Data);
delay_us(1);
LCD_E_L();
LCD_RW_H();
LCD_CSB_H();
LCD_CSA_H();
LCD_E_H();
}
void LCD_Init(void)
{
int i;
@near u8 *p;
p = (u8*)DisplayBuffer;
GPIO_Init(LCD_DATA_PORT, LCD_DATA_PIN, GPIO_MODE_OUT_PP_HIGH_FAST);
GPIO_Init(LCD_CONTROL_PORT, (LCD_E_PIN|LCD_RS_PIN|LCD_RW_PIN), GPIO_MODE_OUT_PP_HIGH_FAST);
GPIO_Init(LCD_CS_PORT, (LCD_CSA_PIN|LCD_CSB_PIN), GPIO_MODE_OUT_PP_HIGH_FAST);
GPIO_Init(LCD_RES_PORT, LCD_RES_PIN, GPIO_MODE_OUT_PP_HIGH_FAST);
for(i = 0; i < 192*8; ++i, ++p)
*p = 0;
LCD_WriteCommand(LCD_DISPLAY_ON, LCD_LEFT);
LCD_WriteCommand(LCD_DISPLAY_ON, LCD_MID);
LCD_WriteCommand(LCD_DISPLAY_ON, LCD_RIGHT);
LCD_WriteCommand(LCD_START_LINE+0, LCD_LEFT);
}
void LCD_BufferDrawPixel(u8 x, u8 y, DrawMode mode)
{
char DX = (y >> 3); // 计算字节
char BX = (y & 0x07); // 计算是字节的第几位
u8 temp = (1<<BX);
switch(mode){
case LCD_CLEAR:
DisplayBuffer &= ~(1<<BX);
break;
case LCD_NOT:
DisplayBuffer ^= (1<<BX);
break;
case LCD_SET:
DisplayBuffer |= (1<<BX);
break;
default:
break;
}
}
// (x,y) Start Point
static void LCD_BufferDrawXLine(u8 x, u8 y, u8 len, DrawMode mode)
{
u8 DX = (y >> 3);
u8 BX = (y & 0x07);
u8 mask = (1 << BX);
u8 nmask = ~mask;
u8 i;
for( i = 0; i < len; ++i,++x)
switch(mode){
case LCD_CLEAR:
DisplayBuffer &= nmask;
break;
case LCD_NOT:
DisplayBuffer ^= mask;
break;
case LCD_SET:
DisplayBuffer |= mask;
break;
default:
break;
}
}
// (x,y) Start Point
static void LCD_BufferDrawYLine(u8 x, u8 y, u8 len, DrawMode mode)
{
u8 DX = (y >> 3);
u8 BX = (y & 0x07);
switch(mode){
case LCD_CLEAR:
DisplayBuffer &= ~(0xff << BX);
break;
case LCD_NOT:
DisplayBuffer ^= (0xff << BX);
break;
case LCD_SET:
DisplayBuffer |= (0xff << BX);
break;
default:
break;
}
DX++;
len -= (8-BX);
while( len >= 8 )
{
switch(mode){
case LCD_CLEAR:
DisplayBuffer &= 0;
break;
case LCD_NOT:
DisplayBuffer ^= 0xff;
break;
case LCD_SET:
DisplayBuffer |= 0xff;
break;
default:
break;
}
DX++;
len -= 8;
}
if(len)
{
switch(mode){
case LCD_CLEAR:
DisplayBuffer &= (0xff << len);
break;
case LCD_NOT:
DisplayBuffer ^= ~(0xff << len);
break;
case LCD_SET:
DisplayBuffer |= ~(0xff << len);
break;
default:
break;
}
}
}
#define abs(x) ((x>0)?(x):(-(x)))
void LCD_BufferDrawLine(u8 x1, u8 y1, u8 x2, u8 y2, DrawMode mode)
{
int dx = x2 - x1;
int dy = y2 - y1;
int x = x1;
int y = y1;
int d;
int incrE;
int incrNE;
if( 0 == dx )
LCD_BufferDrawYLine(x1, y1, dy, mode);
else if( 0 == dy )
LCD_BufferDrawXLine(x1, y1, dx, mode);
else
{
// Bresenham Midpoint Line
if( abs(dx) > abs(dy) )
{ // 0 < k < 1
d = 2 * dy - dx;
incrE = 2 * dy;
incrNE = 2 * (dy - dx);
while( x < x2 )
{
LCD_BufferDrawPixel(x, y, mode);
x++;
if( d > 0 )
{
y++;
d += incrNE;
}
else
d += incrE;
}
LCD_BufferDrawPixel(x, y, mode);
}
else
{ // k > 1
d = 2 * dx - dy;
incrE = 2 * dy;
incrNE = 2 * (dy - dx);
while( y < y2 )
{
LCD_BufferDrawPixel(x, y, mode);
y++;
if( d > 0 )
{
x++;
d += incrNE;
}
else
d += incrE;
}
LCD_BufferDrawPixel(x, y, mode);
}
}
}
void LCD_BufferToLCD(void)
{
u8 i, j;
for( i = 0; i < 8; ++i )
{
LCD_WriteCommand( LCD_XPAGE_BASE + i, LCD_LEFT );
LCD_WriteCommand( LCD_YADDR_BASE + 0, LCD_LEFT);
for( j = 0; j < 64; ++j)
LCD_WriteData(DisplayBuffer, LCD_LEFT);
LCD_WriteCommand( LCD_XPAGE_BASE + i, LCD_MID );
LCD_WriteCommand( LCD_YADDR_BASE + 0, LCD_MID );
for( ; j < 128; ++j)
LCD_WriteData(DisplayBuffer, LCD_MID);
LCD_WriteCommand( LCD_XPAGE_BASE + i, LCD_RIGHT);
LCD_WriteCommand( LCD_YADDR_BASE + 0, LCD_RIGHT );
for( ; j < 192; ++j)
LCD_WriteData(DisplayBuffer, LCD_RIGHT);
}
} 用于测试的主程序
void main(void)
{
LCD_Init();
LCD_BufferToLCD();
LCD_BufferDrawPixel(0, 0, LCD_SET);
LCD_BufferDrawPixel(63, 63, LCD_SET);
LCD_BufferDrawPixel(80, 23, LCD_SET);
LCD_BufferDrawPixel(191, 9, LCD_SET);
LCD_BufferDrawLine(0, 0, 191, 63, LCD_SET);
LCD_BufferDrawLine(0, 2, 0, 60, LCD_SET);
LCD_BufferDrawLine(0, 0, 191, 0, LCD_SET);
/* Infinite loop */
while (1)
{
LCD_BufferToLCD();
}
} 我试过直接画点到LCD和用缓冲区两种方案,速度都很慢,画完整个屏幕大约用掉1秒,这个速度怎么显示波形?
用的是板子上的PB口接的LCD的DB0~DB7
因为板子上的PB0~PB2引脚用0欧电阻接电容接地了,这个会不会对速度有影响? 应该会有影响
可以使用别的IO代替呀 /*
19264测试程式,stm8207s8
*/
#include "stm8s207r.h" /* Registers and memory mapping file. */
#define E_H PA_ODR |= (1<<4)
#define E_L PA_ODR &= ~(1<<4)
#define RW_H PA_ODR |= (1<<5)
#define RW_L PA_ODR &= ~(1<<5)
#define DI_H PA_ODR |= (1<<6)
#define DI_L PA_ODR &= ~(1<<6)
#define CSB_H PG_ODR |= 0X02
#define CSB_L PG_ODR &= ~0X02
#define CSA_H PG_ODR |= 0X01
#define CSA_L PG_ODR &= 0XFE
#define RES_H PE_ODR |= 0X01
#define RES_L PE_ODR &= ~0X01
#define DB PB_ODR
#define ON 1
#define OFF 0
#define CMD 0
#define DAT 1
#define RIGHT 0
#define MID 1
#define LEFT 2
#define u_char unsigned char
#define ADD_Y0 0x40
#define ADD_X0 0xB8
#define DISP_SL0 0xC0
#define DISP_ON 0x3F
#define DISP_OFF 0x3E
#define OSC 8000000L
#if(OSC==1000000)
#define NOP 1
#endif
#if(OSC==8000000)
#define NOP 9
#endif
u_char const chars={
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0xE0,0xE0,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x10,0x30,0x30,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x18,0x1C,0x1C,0x18,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x80,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xF7,0xFF,0xFF,0xFF,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xF8,0xFE,0xFC,0x38,0x10,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xE2,0xFE,0xFE,0xFE,0x7A,0x32,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x03,0x03,0x03,0x03,0x03,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xF0,0x7C,0x3F,0x0F,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x18,0x70,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0xFF,0x3F,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0xC0,0xE0,0xF0,0xF8,0xDE,0xC7,0xC3,0xC1,0xC0,0xC0,0xC0,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0x20,0x20,0x30,0x33,0x3F,0x7F,0xFE,0xFC,0xF0,0x00,0x00,0x00,0x80,0xE0,0xF8,0xFE,0x3F,0x0F,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x01,0x07,0x07,0x07,0x03,0x03,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x83,0xC3,0xF1,0x78,0x3C,0x1E,0x0F,0x03,0x01,0x00,0x00,0x00,0x00,0x40,0x40,0xC0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xC0,0xF0,0xFF,0xFF,0x3F,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x18,0x0C,0x06,0x07,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x1F,0x1F,0x0F,0x07,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"动",2*/
};
u_char const chars1={
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x60,0xC0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xF0,0xF0,0xE0,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x04,0x0C,0x04,0x04,0x04,0x04,0x04,0x04,0xFC,0xFC,0xFC,0x7C,0x04,0x04,0x04,0x04,0x06,0x07,0x07,0x07,0x06,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x1F,0x7F,0x3F,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xF0,0x3F,0x0F,0x07,0x01,0x00,0x00,0x00,0x00,0x80,0xC0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFE,0xFF,0x7F,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x03,0x03,0x03,0x03,0xE1,0xF9,0xF9,0xF1,0x31,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xF1,0xFD,0xF9,0x79,0x31,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xF0,0xFE,0xFF,0xFF,0x17,0x10,0x10,0x10,0x10,0x10,0x10,0xF8,0xFC,0xFC,0x38,0x10,0x00,0x00,0x00,0x80,0xF0,0xFE,0x3F,0x0F,0x03,0x00,0x00,0x80,0xF0,0xFE,0xFE,0x3C,0x18,0x08,0x00,0x00,0xC0,0xF8,0x7F,0x1F,0x07,0x01,0x00,0x00,0x00,0xE0,0xFC,0xF8,0xF0,0x30,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0xC0,0xF0,0x7C,0x1F,0x0F,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x40,0xE0,0xF0,0xF8,0xFE,0xE7,0xE3,0x60,0x60,0x60,0x20,0xE0,0xFC,0x7F,0x1F,0x07,0x01,0x00,0x00,0x70,0xF8,0xFE,0xE7,0x61,0x60,0x20,0x20,0x20,0xA0,0xF0,0xFE,0x7F,0x1F,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x03,0x01,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x03,0x01,0x01,0x00,0x00,0xC0,0xF0,0x7C,0x1F,0x07,0x01,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0xC0,0xF0,0x7E,0x1F,0x07,0x01,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x7F,0x7F,0x3F,0x00,0x80,0xC0,0xE0,0xF0,0xDC,0xCF,0xC3,0xC1,0xE0,0xE0,0x60,0x60,0x20,0x23,0x3F,0xFE,0xFC,0xF0,0xC0,0x00,0xC0,0xE0,0xF8,0xDE,0xC7,0xC1,0xC0,0xC0,0xC0,0x40,0x60,0x61,0x2F,0xFE,0xFC,0xF0,0xE0,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x07,0x07,0x03,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x03,0x00,0x00,0x00,0x03,0x03,0x03,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x07,0x00,0x00,0x00,0x00},/*"磁",1*/
};
u_char const chars2={
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xF0,0xE0,0xC0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xF0,0xF0,0x60,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xF0,0xE0,0xE0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xF0,0x78,0x3E,0x1F,0x07,0x03,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0xFC,0xFC,0xF8,0x18,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0xFC,0xFC,0xF8,0x18,0x08,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x3F,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x0C,0x06,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0xE0,0xF8,0xFE,0xFC,0x3C,0x18,0x00,0x20,0x7F,0xFF,0x7F,0x20,0x20,0x20,0x20,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x20,0xFF,0x7F,0x7F,0x00,0x00,0x00,0x00,0x80,0xF0,0xFF,0xFF,0x1F,0x11,0x10,0x10,0x10,0x10,0x10,0x90,0xF0,0xF0,0xF8,0x1C,0x1F,0x1C,0x18,0x10,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xE0,0xF8,0x3C,0xFF,0xFF,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x38,0x38,0x30,0x20,0x40,0xE0,0x78,0x1F,0x07,0x01,0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x60,0x30,0x1C,0x06,0x03,0x01,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0xF0,0xF0,0x20,0x20,0x20,0x20,0x20,0x30,0xF8,0xFC,0xF8,0x30,0x00,0x00,0x07,0x01,0x00,0x00,0x00,0x00,0x0F,0xFF,0xF8,0x80,0x00,0x00,0xF0,0xFF,0xFF,0x1F,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0x3F,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x80,0xC0,0xC0,0x60,0x30,0x18,0x0C,0x00,0x00,0x00,0x03,0xDF,0xFF,0xFC,0xFF,0xFF,0x8F,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x80,0xE0,0x78,0x1F,0x0F,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x0F,0x1F,0x3F,0x0F,0x07,0x81,0x80,0xC0,0xE0,0xF0,0x70,0x38,0x3C,0x1E,0x0F,0x07,0x03,0x03,0x07,0x1F,0x3F,0x7E,0xFC,0xF8,0xF0,0xE0,0xE0,0xC0,0x80,0x80,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x0F,0x00,0x00,0x04,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x08,0x08,0x0C,0x04,0x06,0x07,0x03,0x03,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x03,0x01,0x00,0x00,0x00,0x00,0x00},/*"微",0*/
};
void vDelay(unsigned int time_uS)
{
while(time_uS--)
{
_asm("nop\n");
//asm ("nop"::);
// asm ("nop"::);
}
}
void vLCD_WR(u_char cDatas,
u_char cSl_chip,
u_char cDat_type)
{
E_L;
RW_L;
if(cSl_chip==RIGHT)
{
CSB_L;
CSA_H;
}else if(cSl_chip==MID)
{
CSB_H;
CSA_L;
}else
{
CSB_L;
CSA_L;
}
if(cDat_type==CMD)
{
DI_L;
}else
{
DI_H;
}
E_H;
DB=cDatas;
vDelay(1*NOP);
E_L;
RW_H;
E_H;
CSB_H;
CSA_H;
}
u_char cLCD_RD( u_char cSl_chip,
u_char cDat_type )
{
u_char m_cDatas;
E_L;
RW_H;
if(cSl_chip==RIGHT)
{
CSB_L;
CSA_H;
}else if(cSl_chip==MID)
{
CSB_H;
CSA_L;
}else
{
CSB_L;
CSA_L;
}
if(cDat_type==CMD)
{
DI_L;
}else
{
DI_H;
}
E_H;
vDelay(1*NOP);
m_cDatas=DB;
RW_L;
E_H;
CSB_H;
CSA_H;
return(m_cDatas);
}
/*
void vLCD_Init(void)
{
u_char m_cAdd_X,m_cAdd_Y,m_cChip;
u_char m_cCount,m_Tmp;
u_char m_cDisp_mod,m_cDisp_sl;
u_char m_cmd=0;
u_char m_dat=1;
DDRA=0xFF; //端口配制为输出
DDRB=0xFF;
DDRD=0xFF;
PORTA=0xFF;
RES_H;
for(m_cChip=0;m_cChip<3;m_cChip++)
{
m_cAdd_Y =ADD_Y0;
m_cAdd_X =ADD_X0;
m_cDisp_sl =DISP_SL0;
m_cDisp_mod =DISP_ON;
vLCD_WR(m_cDisp_mod,m_cChip,m_cmd);
vLCD_WR(m_cDisp_sl,m_cChip,m_cmd);
for(m_Tmp=0;m_Tmp<8;m_Tmp++)
{
vLCD_WR(m_cAdd_Y,m_cChip,m_cmd);
vLCD_WR(m_cAdd_X,m_cChip,m_cmd);
for(m_cCount=0;m_cCount<64;m_cCount++)
{
vLCD_WR(0x00,m_cChip,m_dat); //清屏操作
}
m_cAdd_X++;
}
}
}
*/
void GPIO_Init(void)
{
PB_DDR = 0xff;
PB_CR1 = 0xff;
PB_CR2 = 0xff;
PA_DDR |= (1<<4)|(1<<5)|(1<<6); /* Output. */
PA_CR1 |= (1<<4)|(1<<5)|(1<<6); /* PushPull. */
PA_CR2 |= (1<<4)|(1<<5)|(1<<6); /* Output speed up to 10MHz. */
PG_DDR |= 0X03;
PG_CR1 |= 0X03;
PG_CR2 |= 0X03;
PE_DDR |= 0X01;
PE_CR1 |= 0X01;
PE_CR2 |= 0X01;
}
/* -------------------------------------------------------------------------- */
/* ROUTINE NAME: CLK_Init */
/* INPUT/OUTPUT: None. */
/* DESCRIPTION:Initialize the clock source */
/* -------------------------------------------------------------------------- */
void CLK_Init(void)
{
/* Configure HSI prescaler*/
CLK_CKDIVR &= ~0x10; /* 01: fHSI= fHSI RC output/2. */
/* Configure CPU clock prescaler */
CLK_CKDIVR |= 0x01; /* 001: fCPU=fMASTER/2. */
}
int main(void)
{
u_char m_cAdd_X,m_cAdd_Y,m_cChip;
u_char m_cDisp_mod,m_cDisp_sl;
u_char m_cCount,m_Tmp;
u_char *pcChars;
u_char m_cmd=0;
u_char m_dat=1;
// vLCD_Init;
CLK_Init();
GPIO_Init();
RES_H;
pcChars=chars;
pcChars=chars1;
pcChars=chars2;
for(m_cChip=0;m_cChip<3;m_cChip++)
{
m_cAdd_Y =ADD_Y0;
m_cAdd_X =ADD_X0;
m_cDisp_sl =DISP_SL0;
m_cDisp_mod =DISP_ON;
vLCD_WR(m_cDisp_mod,m_cChip,m_cmd);
vLCD_WR(m_cDisp_sl,m_cChip,m_cmd);
for(m_Tmp=0;m_Tmp<8;m_Tmp++)
{
vLCD_WR(m_cAdd_Y,m_cChip,m_cmd);
vLCD_WR(m_cAdd_X,m_cChip,m_cmd);
for(m_cCount=0;m_cCount<64;m_cCount++)
{
vLCD_WR(*(pcChars++),m_cChip,m_dat);
}
m_cAdd_X++;
}
}
while(1);
return(0);
}
这个代码却非常的快。 这个看起来不太像个51的程序.... 如果是黑白屏,1秒的速度刷屏,不大可能,除非你的主频调的很低 果然是PB0~PB2口已经接的电容影响了速度;电容大小0.47uf,时间常数RC影响了数据线上数据变化的速度,使得必须加大延时才能显示正常。
换了io口后,现在每秒能刷新30祯左右。现在是这样来写的数据,太难看了:(
#define LCD_SET_DATA(x) (PB_ODR = x&0xf0, PC_ODR=(x<<4), PE_ODR=(x&0x01))
PB口的高4位,PC的高3位,PE的第0位,凑出来一个8位并行口。 ifree64兄弟真的很快啊。
等PCB和按键确定,我就该写状态机部分了 终于调出来了任意斜率的Breseham中点法画直线的代码
#define abs(x) ((x>0)?(x):(-(x)))
void LCD_BufferDrawLine(u8 x1, u8 y1, u8 x2, u8 y2, DrawMode mode)
{
u8 x, y, t;
int dx, dy, d, incrE, incrNE;
if( y1 > y2)
{
t = x1, x1 = x2, x2 = t;
t = y1, y1 = y2, y2 = t;
}
dx = x2 - x1;
dy = y2 - y1;
x = x1, y = y1;
if( 0 == dx )
{
LCD_BufferDrawYLine(x1, y1, dy, mode);
}
else if( 0 == dy )
{
if( x1 > x2 )
LCD_BufferDrawXLine(x2, y2, dx, mode);
else
LCD_BufferDrawXLine(x1, y1, dx, mode);
}
else
{
// Bresenham Midpoint Line
if( abs(dx) > abs(dy) )
{
if( x2 > x1)
{
// 0 < k < 1
d = 2 * dy - dx;
incrE = 2 * dy;
incrNE = 2 * (dy - dx);
while( x < x2 )
{
LCD_BufferDrawPixel(x, y, mode);
x++;
if( d > 0 )
{
y++;
d += incrNE;
}
else
d += incrE;
}
LCD_BufferDrawPixel(x, y, mode);
}
else
{
// -1 < k < 0
d = -2 * dy - dx;
incrE = -2 * dy;
incrNE = -2 * (dy + dx);
while( x > x2)
{
LCD_BufferDrawPixel(x, y, mode);
x--;
if( d < 0 )
{
y++;
d += incrNE;
}
else
d += incrE;
}
LCD_BufferDrawPixel(x, y, mode);
}
}
else
{
if( x2 > x1)
{
// k > 1
d = dy - 2 * dx;
incrE = -2 * dx;
incrNE = 2 * (dy - dx);
while( y < y2 )
{
LCD_BufferDrawPixel(x, y, mode);
y++;
if( d < 0 )
{
x++;
d += incrNE;
}
else
d += incrE;
}
LCD_BufferDrawPixel(x, y, mode);
}
else
{
// k < -1
d = -dy - 2 * dx;
incrE = -2 * dx;
incrNE = -2 * (dy + dx);
while( y < y2 )
{
LCD_BufferDrawPixel(x, y, mode);
y++;
if( d > 0 )
{
x--;
d += incrNE;
}
else
d += incrE;
}
LCD_BufferDrawPixel(x, y, mode);
}
}
}
} 【4楼】的代码速度
http://cache.amobbs.com/bbs_upload782111/files_13/ourdev_429783.JPG
(原文件名:stm8lcd1.JPG)
修改的代码
点击此处下载 ourdev_429790.rar(文件大小:2K) (原文件名:main.rar)
修改的代码速度
http://cache.amobbs.com/bbs_upload782111/files_13/ourdev_429784.JPG
(原文件名:stm8lcd2.JPG) 谢谢楼上优化后的代码,我新写的代码也直接操作寄存器,没有用固件库了。但楼上的代码在LCD上测试过吗?LCD能不能忙得过来?
我现在发现问题不是代码的速度跟不跟得上,而是LCD没有那么快。
比如,在void vLCD_WR(u_char cDatas, u_char cSl_chip, u_char cDat_type)函数里需要延时,我将时钟频率调快后,必须将延时加大才行。
不过按LCD的手册来看,E脉冲的周期1us就够了,如果按照这个来算,写192*8字节应该可以在2ms以内完成,但是好像实测达不到。 我没有LCD,没有目标板,没有仿真器,只能用软件仿真一下,
图中PA_ODR就是E的波形
http://cache.amobbs.com/bbs_upload782111/files_13/ourdev_429852.JPG
(原文件名:stm8slcd.JPG) mark 记号! 12楼的你用的是什么仿真器啊 mark mark mark 记号 这个:iostm8a.h 在哪里? MNA 标记一下 MARK 19264lcd 顶 关于软件,我的划线程序,改良别人的
if ( mode == Pix_CLEAR )
{for(x=x1;x<=x2;x++) LcdPixBuf &= (~(0x80 >> offset)); }
else if ( mode == Pix_DRAW )
{for(x=x1;x<=x2;x++) LcdPixBuf |= (0x80 >> offset); }
else // if ( mode== Pix_XOR )
{for(x=x1;x<=x2;x++) LcdPixBuf ^= (0x80 >> offset); }
这个for放在mode判断的后面,代码多了些,速度却快些了,不用每个位判断。
void LcdDrawLine(uint8 x1, uint8 y1, uint8 x2, uint16 y2)
{
uint16 x, y, t;
if((x1==x2)&&(y1==y2))LcdCachePix(x1, y1,Pix_DRAW);
else if(abs(y2-y1)>abs(x2-x1))//斜率大于1
{
if(y1>y2)
{
t=y1;
y1=y2;
y2=t;
t=x1;
x1=x2;
x2=t;
}
for(y=y1;y<y2;y++)//以y轴为基准
{
x=(uint16)(y-y1)*(x2-x1)/(y2-y1)+x1;
LcdCachePix((uint8)x,(uint8)y,Pix_DRAW);
}
}
else //斜率小于等于1
{
if(x1>x2)
{
t=y1;
y1=y2;
y2=t;
t=x1;
x1=x2;
x2=t;
}
for(x=x1;x<=x2;x++)//以x轴为基准
{
y =(uint16)(x-x1)*(y2-y1)/(x2-x1)+y1;
LcdCachePix((uint8)x, (uint8)y,Pix_DRAW);
}
}
}
void LcdDrawLineH(uint8 x1, uint8 y1, uint8 x2, LcdPixMode mode)
{
byterow,x,y;;
byteoffset;
row = y / 8;
offset= y % 8;
if ( mode == Pix_CLEAR )
{for(x=x1;x<=x2;x++) LcdPixBuf &= (~(0x80 >> offset)); }
else if ( mode == Pix_DRAW )
{for(x=x1;x<=x2;x++) LcdPixBuf |= (0x80 >> offset); }
else // if ( mode== Pix_XOR )
{for(x=x1;x<=x2;x++) LcdPixBuf ^= (0x80 >> offset); }
} fixed小于一个字节的错误
void LcdDrawLineV(uint8 x, uint8 y, int8 len, LcdPixMode mode)
{ uint8 PixByte;
uint8 row = (y >> 3);
uint8 offset = (y & 0x07);
PixByte = 0xFF >> offset;
if (len<=(8-offset)) {
PixByte >>= (8-offset-len);
PixByte <<= (8-offset-len);
}
switch(mode){ // first column
case Pix_CLEAR:
LcdPixBuf &= ~(PixByte);
break;
case Pix_XOR:
LcdPixBuf ^= (PixByte);
break;
case Pix_DRAW:
LcdPixBuf |= (PixByte);
break;
default:
break;
}
if (len<=(8-offset)) return;
row++;
len -= (8-offset);
while( len >= 8 ) //mid whole column byte
{
switch(mode){
case Pix_CLEAR:
LcdPixBuf &= 0;
break;
case Pix_XOR:
LcdPixBuf ^= 0xff;
break;
case Pix_DRAW:
LcdPixBuf |= 0xff;
break;
default:
break;
}
row++;
len -= 8;
}
if(len){ // last column
switch(mode){
case Pix_CLEAR:
LcdPixBuf &= (0xff >> len);
break;
case Pix_XOR:
LcdPixBuf ^= ~(0xff >> len);
break;
case Pix_DRAW:
LcdPixBuf |= ~(0xff >> len);
break;
default:
break;
}
}
} 很有技术含量嘛,值得学习 进来学习 mark学习了 该帖子高质量顶上去 cool 马克马克!有机会试试,手头没有这号液晶。。。。等过几天弄而来玩玩 学习了!顶下 mark。。。。画线。 支持一下,没做这块,路过 不错,mark! 好贴,MARK! 谢谢分享!!!!!!!!!!!!!! 学习一下 正好有个项目需要这个屏 嗯嗯,参考下想移植到AVR上面 感觉很牛B的样子 {:2_27:}{:2_27:}{:2_27:}{:2_27:}
页:
[1]