|
利用STM32 USART1 和 GPIO驱动 NOKIA 6100、3100手机LCD(PCF8833)
1:GPIO模拟同步串行口驱动
2:USART1同步模式驱动
得出的结论:
1:PCF8833数据顺序:1位DATA/COMMAND + 1byte(MSB)
2:STM32的SPI只能8/16位发送,因而不适合驱动PCF8833,MSB/LSB可以更改
3:USART可以工作在同步8/9bit模式,但只按LSB发送,不能更改为MSB,驱动时需要软件更改,这点不爽
4:PCF8833的接口频率是不是有点低?USART最大工作到550Kbps,再高PCF8833就不行了,132*132全屏幕更新时需要0.5S左右,汗!
AVR的好象这点比他强...
_________________________________________________________________________________________________________________________________________
#include "stm32f10x_lib.h"
#include "LCD3100.h"
// *****************************************************************************
// Function Name : _HardwareConfig
// Description : LCD3100 hardware configuration: I/O or USART
// Input : None
// Output : None
// Return : None
// *****************************************************************************
void _HardwareConfig(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
#ifdef LCD_DIRVER_USART
USART_InitTypeDef usart_init_struct;
USART_ClockInitTypeDef usart_clock_init_struct;
// Enable GPIOA and USART1 clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
// USRAT1 SCK[PA8] -> LCD3100 SCK
// USART1 TXD[PA9] -> LCD3100 SDA
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
// GPIOA PA6 -> LCD3100 RST
GPIO_InitStruct.GPIO_Pin = LCD3100_RST;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStruct);
// USART1 in synchro-mode
usart_init_struct.USART_BaudRate = USART_BR;
usart_init_struct.USART_WordLength = USART_WordLength_9b;
usart_init_struct.USART_StopBits = USART_StopBits_1;
usart_init_struct.USART_Parity = USART_Parity_No;
usart_init_struct.USART_Mode = USART_Mode_Tx;
usart_init_struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART1, &usart_init_struct);
usart_clock_init_struct.USART_Clock = USART_Clock_Enable;
usart_clock_init_struct.USART_CPOL = USART_CPOL_Low;
usart_clock_init_struct.USART_CPHA = USART_CPHA_1Edge;
usart_clock_init_struct.USART_LastBit = USART_LastBit_Enable;
USART_ClockInit(USART1, &usart_clock_init_struct);
// Enable USART
USART_Cmd(USART1, ENABLE);
#else
// Enable GPIOA clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStruct.GPIO_Pin = LCD3100_RST | LCD3100_SDA | LCD3100_SCK;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
#endif
}
// *****************************************************************************
// Function Name : _Reset
// Description : LCD3100 hardware reset
// Input : None
// Output : None
// Return : None
// *****************************************************************************
void _Reset(void)
{
unsigned short i;
unsigned short j;
for(i=0;i<5000;i++)
for(j=0;j<500;j++);
GPIO_SetBits(GPIOA, LCD3100_RST);
}
// *****************************************************************************
// Function Name : _IOM_Delay
// Description : I/O Mode delay sometimes for LCD3100
// Input : None
// Output : None
// Return : None
// *****************************************************************************
void _IOM_Delay(void)
{
unsigned char i;
for(i=0; i<18; i++);
}
// *****************************************************************************
// Function Name : LCD_GPIO_SendBit
// Description : I/O Mode send 1Byte data bit by bit
// Input : -uc_byte: 1byte data be send
// -uc_bit: 1byte data bit
// Output : None
// Return : None
// *****************************************************************************
void _IOM_SendBit(unsigned char uc_byte, unsigned char uc_bit)
{
GPIO_SetBits(GPIOA, LCD3100_SCK);
if(uc_byte&uc_bit)
GPIO_SetBits(GPIOA, LCD3100_SDA);
else
GPIO_ResetBits(GPIOA, LCD3100_SDA);
_IOM_Delay();
GPIO_ResetBits(GPIOA, LCD3100_SCK);
_IOM_Delay();
}
// *****************************************************************************
// Function Name : LCD_GPIO_SendByte
// Description : I/O Mode send 1Byte data
// Input : -uc_byte: 1byte data be send
// Output : None
// Return : None
// *****************************************************************************
void _IOM_SendByte(unsigned char uc_byte)
{
_IOM_SendBit(uc_byte, 0x80);
_IOM_SendBit(uc_byte, 0x40);
_IOM_SendBit(uc_byte, 0x20);
_IOM_SendBit(uc_byte, 0x10);
_IOM_SendBit(uc_byte, 0x08);
_IOM_SendBit(uc_byte, 0x04);
_IOM_SendBit(uc_byte, 0x02);
_IOM_SendBit(uc_byte, 0x01);
}
// *****************************************************************************
// Function Name : LCD_SendData
// Description : Can use I/O and USART mode send 1byte data to LCD3100
// Input : 1byte data be send
// Output : None
// Return : None
// *****************************************************************************
void LCD_SendData(unsigned char uc_data)
{
#ifdef LCD_DIRVER_USART
unsigned char i = 0;
unsigned char t = 0;
for(i=0;i<8;i++)
{
if(((1<<i)&uc_data)) t|=(1<<(7-i));
}
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
USART_SendData(USART1, (t<<1)|0x0001);
#else
GPIO_SetBits(GPIOA, LCD3100_SCK);
GPIO_SetBits(GPIOA, LCD3100_SDA);
_IOM_Delay();
GPIO_ResetBits(GPIOA, LCD3100_SCK);
_IOM_Delay();
_IOM_SendByte(uc_data);
#endif
}
// *****************************************************************************
// Function Name : LCD_SendCommand
// Description : Can use I/O and USART mode Send 1byte command to LCD3100
// Input : 1byte command be send
// Output : None
// Return : None
// *****************************************************************************
void LCD_SendCommand(unsigned char uc_data)
{
#ifdef LCD_DIRVER_USART
unsigned char i = 0;
unsigned char t = 0;
for(i=0;i<8;i++)
{
if(((1<<i)&uc_data)) t|=(1<<(7-i));
}
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
USART_SendData(USART1, t<<1);
#else
GPIO_SetBits(GPIOA, LCD3100_SCK);
GPIO_ResetBits(GPIOA, LCD3100_SDA);
_IOM_Delay();
GPIO_ResetBits(GPIOA, LCD3100_SCK);
_IOM_Delay();
_IOM_SendByte(uc_data);
#endif
}
// *****************************************************************************
// Function Name : LCD_FillRect
// Description : Use a color brush fill a rectangle area
// Input : -x: rectangle x-position
// -y: rectangle y-position
// -cx: rectangle x-size
// -cy: rectangle y-size
// -r: RGB color
// -g: RGB color
// -b: RGB color
// Output : None
// Return : None
// *****************************************************************************
void LCD_FillRect
(
unsigned char x,
unsigned char y,
unsigned char cx,
unsigned char cy,
unsigned char r,
unsigned char g,
unsigned char b
)
{
unsigned int i = 0;
unsigned int t = cx*cy;
LCD_SetActiveRect(x, y, cx, cy);
LCD_SendCommand(PCF8833_RAMWRITE);
for(i=0; i<t; i++)
{
LCD_SendData( (r<<3) | (g>>3) );
LCD_SendData( (g<<5) | b );
}
}
// *****************************************************************************
// Function Name : LCD_DrawBitmap
// Description : Draw a RGB[5:6:5] bitmap
// Input : -x: bitmap x-position
// -y: bitmap y-position
// -cx: bitmap x-size
// -cy: bitmap y-size
// -cuc_bmp: bitmap data
// Output : None
// Return : None
// *****************************************************************************
void LCD_DrawBitmap
(
unsigned char x,
unsigned char y,
unsigned char cx,
unsigned char cy,
const unsigned char* cuc_bmp
)
{
unsigned int i;
unsigned int t = 2*cx*cy;
LCD_SetActiveRect(x, y, cx, cy);
LCD_SendCommand(PCF8833_RAMWRITE);
for(i=0; i<t; i++)
{
LCD_SendData(*(cuc_bmp+i));
}
}
// *****************************************************************************
// Function Name : LCD_SetActiveRect
// Description : Choose a active rectangle area for draw
// Input : -x: rectangle x-position
// -y: rectangle y-position
// -cx: rectangle x-size
// -cy: rectangle y-size
// Output : None
// Return : None
// *****************************************************************************
void LCD_SetActiveRect
(
unsigned char x,
unsigned char y,
unsigned char cx,
unsigned char cy
)
{
LCD_SendCommand(PCF8833_COLUMNSET);
LCD_SendData(x);
LCD_SendData(x+cx-1);
LCD_SendCommand(PCF8833_PAGESET);
LCD_SendData(y);
LCD_SendData(y+cy-1);
}
// *****************************************************************************
// Function Name : LCD_Init
// Description : LCD3100 initialization
// Input : None
// Output : None
// Return : None
// *****************************************************************************
void LCD_Init(void)
{
_HardwareConfig();
// hardware reset
_Reset();
// sleep out
LCD_SendCommand(PCF8833_SLEEPOUT);
// color interface pixel format
LCD_SendCommand(PCF8833_COLMOD);
LCD_SendData(0x05); // 16-bit
// set contrast
LCD_SendCommand(PCF8833_SETCON);
LCD_SendData(58);
// color set: look-up table
LCD_SendCommand(PCF8833_COLORSET);
// red tone
LCD_SendData(0x00);
LCD_SendData(0x02);
LCD_SendData(0x04);
LCD_SendData(0x06);
LCD_SendData(0x09);
LCD_SendData(0x0B);
LCD_SendData(0x0D);
LCD_SendData(0x0F);
// green tone
LCD_SendData(0x00);
LCD_SendData(0x02);
LCD_SendData(0x04);
LCD_SendData(0x06);
LCD_SendData(0x09);
LCD_SendData(0x0B);
LCD_SendData(0x0D);
LCD_SendData(0x0F);
// blue tone
LCD_SendData(0x00);
LCD_SendData(0x07);
LCD_SendData(0x0B);
LCD_SendData(0x0F);
// display on
LCD_SendCommand(PCF8833_DISPON);
}
_________________________________________________________________________________________________________________________________________
#ifndef __LCD3100_H
#define __LCD3100_H
// *****************************************************************************
// LCD3100-PCF8833
//
// 1: 3100_VCC -> 3.3V
// 2: 3100_RST -> STM32_PA6 GPIO
// 3: 3100_SDA -> STM32_PA7 USART1 TX
// 4: 3100_SCK -> STM32_PA5 USART1 SCK
// 5: 3100_NCS -> 0V
// 6: 3100_VLCD -> 3.3V
// 7: NC
// 8: GND -> 0V
// 9: LED- -> 0V
// 10: LED+ -> 6V
// *****************************************************************************
// Dirve by USART1
#define LCD_DIRVER_USART
// USART1 BaudRate for LCD3100
#define USART_BR 500000 // bit/s
// For GPIO controled
#define LCD3100_RST GPIO_Pin_6
#define LCD3100_SDA GPIO_Pin_7
#define LCD3100_SCK GPIO_Pin_5
// command will be used
#define PCF8833_SLEEPOUT 0x11
#define PCF8833_COLMOD 0x3A
#define PCF8833_SETCON 0x25
#define PCF8833_DISPON 0x29
#define PCF8833_COLUMNSET 0x2A
#define PCF8833_PAGESET 0x2B
#define PCF8833_RAMWRITE 0x2C
#define PCF8833_COLORSET 0x2D
// This group for user
void LCD_Init(void);
void LCD_SendCommand(unsigned char uc_data);
void LCD_SendData(unsigned char uc_data);
void LCD_SetActiveRect
(
unsigned char x,
unsigned char y,
unsigned char cx,
unsigned char cy
);
void LCD_FillRect
(
unsigned char x,
unsigned char y,
unsigned char cx,
unsigned char cy,
unsigned char r,
unsigned char g,
unsigned char b
);
void LCD_DrawBitmap
(
unsigned char x,
unsigned char y,
unsigned char cx,
unsigned char cy,
const unsigned char* cuc_bmp
);
// This group only for driver
void _Reset(void);
void _HardwareConfig(void);
void _IOM_Delay(void);
void _IOM_SendByte(unsigned char uc_byte);
void _IOM_SendBit(unsigned char uc_byte, unsigned char uc_bit);
#endif |
阿莫论坛20周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|