搜索
bottom↓
回复: 2

利用STM32 USART1 和 GPIO驱动 NOKIA 6100、3100手机LCD(PCF8833)

[复制链接]

出0入0汤圆

发表于 2008-9-8 15:56:26 | 显示全部楼层 |阅读模式
利用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周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2008-12-10 19:00:43 | 显示全部楼层
楼主强啊,用串口驱动LCD,很好的方法哦,学习了!

出0入0汤圆

发表于 2010-3-16 16:40:44 | 显示全部楼层
又有牛人,
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-16 17:22

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表