Lawrence 发表于 2014-6-26 12:19:20

使用STM32F103VB芯片模拟SPI时序读取字库芯片GT30L32S4W

本帖最后由 jianhong_wu 于 2015-6-17 13:36 编辑

★坚鸿-深圳:
我点评一下,以下代码有段内容很容易出错,尤其是在移植到不同的单片机编译器上的时候,这段代码是在读取字库芯片数据时,参与地址变换的变量GBCode_MSB和GBCode_LSB不应该用8位的字节,很容易溢出出错。比如:
      uint32_t BaseAddr      = 0x2C9D0;                                                                              //16x16点阵的起始地址,见手册《GT23L32S4W用户手册》
      uint8_t GBCode_MSB      = (GBCode >> 8) & 0xFF;                                                      //汉字内码的高八位
      uint8_t GBCode_LSB      = GBCode & 0xFF;                                                                //汉字内码的低八位
      uint32_t WordAddr      = 0;                                                                                        //汉字或者ASCII字符点阵在芯片中的字节地址
      const uint32_t BUFSIZE      = 32;                                                                              //缓冲区的大小
      uint8_t      i;应该改成
      uint32_t BaseAddr      = 0x2C9D0;                                                                              //16x16点阵的起始地址,见手册《GT23L32S4W用户手册》
      uint32_tGBCode_MSB      = (GBCode >> 8) & 0xFF;                                                      //汉字内码的高八位
      uint32_tGBCode_LSB      = GBCode & 0xFF;                                                                //汉字内码的低八位
      uint32_t WordAddr      = 0;                                                                                        //汉字或者ASCII字符点阵在芯片中的字节地址
      const uint32_t BUFSIZE      = 32;                                                                              //缓冲区的大小
      uint8_t      i;

//-------------坚鸿点评分割线------------------------------------------------------------------------------------------------------------------------------------


spi0.h文件

#include "stm32f10x.h"
#include "delay.h"

#ifndef      __SPI0__H_
#define __SPI0__H_

//MISO(MOSI),M是主控CPU,S是SPI字库芯片
#define SPI0_CS_ON()      (GPIO_SetBits(GPIOA, GPIO_Pin_4))                              //拉高
#define SPI0_CS_OFF()      (GPIO_ResetBits(GPIOA, GPIO_Pin_4))                              //拉低

#define SPI0_SCLK_ON()      (GPIO_SetBits(GPIOA, GPIO_Pin_5))                              //拉高
#define SPI0_SCLK_OFF()      (GPIO_ResetBits(GPIOA, GPIO_Pin_5))                              //拉低

#define SPI0_MOSI_ON()      (GPIO_SetBits(GPIOA, GPIO_Pin_7))                              //拉高
#define SPI0_MOSI_OFF()      (GPIO_ResetBits(GPIOA, GPIO_Pin_7))                              //拉低

#define SPI0_MISO_READ()      ((uint8_t)GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6))      //读取MISO的电平

/*******************************************************
*函数名称:SPI0_init
*函数功能:初始化SPI0(驱动字库的模拟SPI接口)的IO口
*入口参数:无
*出口参数:无
******************************************************/
void SPI0_init(void);

/*******************************************************
*函数名称:SPI0_clear
*函数功能:清除SPI总线状态
*入口参数:无
*出口参数:无
******************************************************/
void SPI0_clear(void);

/*******************************************************
*函数名称:SPI0_readByte
*函数功能:SPI0读取一个字节数据
*入口参数:无
*出口参数:unsigned char
******************************************************/
uint8_t SPI0_readByte(void);

/*******************************************************
*函数名称:SPI0_writeByte
*函数功能:SPI0写出一个字节数据
*入口参数:unsigned char
*出口参数:无
******************************************************/
void SPI0_writeByte(uint8_t dat);




#endif      /* end of file */




spi0.c文件

#include "spi0.h"

/*******************************************************
*函数名称:SPI0_init
*函数功能:初始化SPI0(驱动字库的模拟SPI接口)的IO口
*入口参数:无
*出口参数:无
******************************************************/
void SPI0_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
      
      // spi0 gpio configuration
      // CS - PA.4      SCK - PA.5      MISO - PA.6                MOSI - PA.7
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;                                 
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                                        //推挽输出
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                                       //口线翻转速度为50MHz
      GPIO_Init(GPIOA, &GPIO_InitStructure);

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;                                 
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                                        //推挽输出
      GPIO_Init(GPIOA, &GPIO_InitStructure);

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;                                 
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;                                                //上拉输入
      GPIO_Init(GPIOA, &GPIO_InitStructure);

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;                                 
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                                        //推挽输出
      GPIO_Init(GPIOA, &GPIO_InitStructure);

      SPI0_clear();                                                                                                                //清除SPI总线状态
}

/*******************************************************
*函数名称:SPI0_clear
*函数功能:清除SPI总线状态
*入口参数:无
*出口参数:无
******************************************************/
void SPI0_clear(void)
{
      SPI0_CS_ON();                                                                                                                //拉高
      SPI0_SCLK_ON();                                                                                                                //拉高
      SPI0_MOSI_ON();                                                                                                                //拉高
}

/*******************************************************
*函数名称:SPI0_readByte
*函数功能:SPI0读取一个字节数据
*入口参数:无
*出口参数:unsigned char
******************************************************/
uint8_t SPI0_readByte(void)
{
      uint8_t i;
      uint8_t      dat;
      
      for(i = 0; i < 8; i++)
      {
                dat <<= 1;
                SPI0_SCLK_OFF();                                                                                                //下降沿,MISO字库芯片移出一个bit      
                if(SPI0_MISO_READ() == 1)
                {
                        dat |= 0x01;
                }
                else
                {
                        dat |= 0x00;
                }
                delay_nop(2);
                SPI0_SCLK_ON();
                delay_nop(10);
      }
      return dat;
}

/*******************************************************
*函数名称:SPI0_writeByte
*函数功能:SPI0写出一个字节数据
*入口参数:unsigned char
*出口参数:无
******************************************************/
void SPI0_writeByte(uint8_t dat)
{
      uint8_t i;

      for(i = 0; i < 8; i++)
      {
                SPI0_SCLK_OFF();                                                                                                
                if(dat & 0x80)
                {
                        SPI0_MOSI_ON();
                }
                else
                {
                        SPI0_MOSI_OFF();
                }
                dat <<= 1;
                delay_nop(2);
                SPI0_SCLK_ON();                                                                                                      //上升沿,MOSI字库芯片移入一个bit
                delay_nop(10);               
      }
}

字库驱动程序wordlib.h

#include "stm32f10x.h"
#include "delay.h"
#include "spi0.h"

#ifndef      __WORDLIB__H_
#define __WORDLIB__H_

//SPI0模拟时序的底层函数调用封装
#define SPI_CLEAR()                (SPI0_clear())
#define SPI_CS_ON()                (SPI0_CS_ON())
#define SPI_CS_OFF()      (SPI0_CS_OFF())
#define SPI_WRITE_BYTE(dat)                (SPI0_writeByte((dat)))
#define SPI_READ_BYTE()                        (SPI0_readByte())


//指令表
#define CMD_READ_WORDLIB                (0x03)                                                                              //读取数据命令
#define CMD_FASTREAD_WORDLIB      (0x0B)                                                                              //快速读取数据命令
#define CMD_DUMMY                              (0xFF)                                                                              //空指令、假数据

/*===============================================ASCII取码(非扩展等宽字符)==============================================*/
/*******************************************************
*函数名称:WORDLIB_read_ASCII_5x7
*函数功能:读取字库芯片中一个ASCII字符的5x7点阵编码
*入口参数:ASCIICode,ASCII码;buffer,点阵编码的缓冲区;
                                 buffer必须大于等于8个字节。
*出口参数:无
******************************************************/
void WORDLIB_read_ASCII_5x7(uint16_t ASCIICode, uint8_t *buffer);

/*******************************************************
*函数名称:WORDLIB_read_ASCII_7x8
*函数功能:读取字库芯片中一个ASCII字符的7x8点阵编码
*入口参数:ASCIICode,ASCII码;buffer,点阵编码的缓冲区;
                                 buffer必须大于等于8个字节。
*出口参数:无
******************************************************/
void WORDLIB_read_ASCII_7x8(uint16_t ASCIICode, uint8_t *buffer);

/*******************************************************
*函数名称:WORDLIB_read_ASCII_6x12
*函数功能:读取字库芯片中一个ASCII字符的6x12点阵编码
*入口参数:ASCIICode,ASCII码;buffer,点阵编码的缓冲区;
                                 buffer必须大于等于12个字节。
*出口参数:无
******************************************************/
void WORDLIB_read_ASCII_6x12(uint16_t ASCIICode, uint8_t *buffer);

/*******************************************************
*函数名称:WORDLIB_read_ASCII_8x16
*函数功能:读取字库芯片中一个ASCII字符的8x16点阵编码
*入口参数:ASCIICode,ASCII码;buffer,点阵编码的缓冲区;
                                 buffer必须大于等于16个字节。
*出口参数:无
******************************************************/
void WORDLIB_read_ASCII_8x16(uint16_t ASCIICode, uint8_t *buffer);

/*******************************************************
*函数名称:WORDLIB_read_ASCII_12x24
*函数功能:读取字库芯片中一个ASCII字符的12x24点阵编码
*入口参数:ASCIICode,ASCII码;buffer,点阵编码的缓冲区;
                                 buffer必须大于等于48个字节。
*出口参数:无
******************************************************/
void WORDLIB_read_ASCII_12x24(uint16_t ASCIICode, uint8_t *buffer);

/*******************************************************
*函数名称:WORDLIB_read_ASCII_16x32
*函数功能:读取字库芯片中一个ASCII字符的16x32点阵编码
*入口参数:ASCIICode,ASCII码;buffer,点阵编码的缓冲区;
                                 buffer必须大于等于64个字节。
*出口参数:无
******************************************************/
void WORDLIB_read_ASCII_16x32(uint16_t ASCIICode, uint8_t *buffer);




/*===============================================国标汉字取码(非扩展等宽字符)===========================================*/
/*******************************************************
*函数名称:WORDLIB_read_GB_12x12
*函数功能:读取字库芯片中一个国标汉字的12x12点阵编码
*入口参数:GBCode,汉字内码;buffer,点阵编码的缓冲区;
                                 buffer必须大于等于24个字节。
*出口参数:无
******************************************************/
void WORDLIB_read_GB_12x12(uint16_t GBCode, uint8_t *buffer);

/*******************************************************
*函数名称:WORDLIB_read_GB_16x16
*函数功能:读取字库芯片中一个国标汉字的16x16点阵编码
*入口参数:GBCode,汉字内码;buffer,点阵编码的缓冲区;
                                 buffer必须大于等于32个字节。
*出口参数:无
******************************************************/
void WORDLIB_read_GB_16x16(uint16_t GBCode, uint8_t *buffer);

/*******************************************************
*函数名称:WORDLIB_read_GB_24x24
*函数功能:读取字库芯片中一个国标汉字的24x24点阵编码
*入口参数:GBCode,汉字内码;buffer,点阵编码的缓冲区;
                                 buffer必须大于等于72个字节。
*出口参数:无
******************************************************/
void WORDLIB_read_GB_24x24(uint16_t GBCode, uint8_t *buffer);

/*******************************************************
*函数名称:WORDLIB_read_GB_32x32
*函数功能:读取字库芯片中一个国标汉字的32x32点阵编码
*入口参数:GBCode,汉字内码;buffer,点阵编码的缓冲区;
                                 buffer的大小必须是128个字节。
*出口参数:无
******************************************************/
void WORDLIB_read_GB_32x32(uint16_t GBCode, uint8_t *buffer);




#endif      /* end of file */



字库驱动程序wordlib.c

#include "wordlib.h"

/*===============================================ASCII取码(非扩展等宽字符)==============================================*/
/*******************************************************
*函数名称:WORDLIB_read_ASCII_5x7
*函数功能:读取字库芯片中一个ASCII字符的5x7点阵编码
*入口参数:ASCIICode,ASCII码;buffer,点阵编码的缓冲区;
                                 buffer必须大于等于8个字节。
*出口参数:无
******************************************************/
void WORDLIB_read_ASCII_5x7(uint16_t ASCIICode, uint8_t *buffer)
{
      uint32_t BaseAddr      = 0x1DDF80;                                                                              //5x7点阵的起始地址,见手册《GT23L32S4W用户手册》
      uint32_t WordAddr      = 0;                                                                                        //ASCII字符点阵在芯片中的字节地址
      const uint32_t BUFSIZE      = 8;                                                                              //缓冲区的大小
      uint8_t      i;

      //计算地址,见手册《GT23L32S4W用户手册》
      if((ASCIICode >= 0x20) && (ASCIICode <= 0x7E))
      {
                WordAddr      = (ASCIICode - 0x20) * BUFSIZE + BaseAddr;
      }

      SPI_CLEAR();                                                                                                                //清除SPI总线
      delay_nop(10);
      
      //开始快速读取点阵数据:Read Data Bytes At Higher Speed
      SPI_CS_OFF();
      delay_nop(10);
      
      SPI_WRITE_BYTE(CMD_FASTREAD_WORDLIB);                                                                //发送命令字:0x0B
      SPI_WRITE_BYTE((WordAddr >> 16) & 0xff);                                                      //从高到低,依次发送三个字节的地址
      SPI_WRITE_BYTE((WordAddr >> 8) & 0xff);
      SPI_WRITE_BYTE(WordAddr & 0xff);
      SPI_WRITE_BYTE(CMD_DUMMY);                                                                                        //最后发送一个字节的假数据 Dummy Byte
      //delay_nop(10);
      for(i = 0; i < BUFSIZE; i++)
      {
                *(buffer + i)      = SPI_READ_BYTE();                                                                //读取字库芯片发送过来的点阵编码
      }

      SPI_CS_ON();                                                                                                               //CS置高,结束本次操作
      delay_nop(10);

      SPI_CLEAR();                                                                                                                //清除SPI总线
      delay_nop(10);
}

/*******************************************************
*函数名称:WORDLIB_read_ASCII_7x8
*函数功能:读取字库芯片中一个ASCII字符的7x8点阵编码
*入口参数:ASCIICode,ASCII码;buffer,点阵编码的缓冲区;
                                 buffer必须大于等于8个字节。
*出口参数:无
******************************************************/
void WORDLIB_read_ASCII_7x8(uint16_t ASCIICode, uint8_t *buffer)
{

      uint32_t BaseAddr      = 0x1DE280;                                                                              //7x8点阵的起始地址,见手册《GT23L32S4W用户手册》
      uint32_t WordAddr      = 0;                                                                                        //ASCII字符点阵在芯片中的字节地址
      const uint32_t BUFSIZE      = 8;                                                                              //缓冲区的大小
      uint8_t      i;

      //计算地址,见手册《GT23L32S4W用户手册》
      if((ASCIICode >= 0x20) && (ASCIICode <= 0x7E))
      {
                WordAddr      = (ASCIICode - 0x20) * BUFSIZE + BaseAddr;
      }

      SPI_CLEAR();                                                                                                                //清除SPI总线
      delay_nop(10);
      
      //开始快速读取点阵数据:Read Data Bytes At Higher Speed
      SPI_CS_OFF();
      delay_nop(10);
      
      SPI_WRITE_BYTE(CMD_FASTREAD_WORDLIB);                                                                //发送命令字:0x0B
      SPI_WRITE_BYTE((WordAddr >> 16) & 0xff);                                                      //从高到低,依次发送三个字节的地址
      SPI_WRITE_BYTE((WordAddr >> 8) & 0xff);
      SPI_WRITE_BYTE(WordAddr & 0xff);
      SPI_WRITE_BYTE(CMD_DUMMY);                                                                                        //最后发送一个字节的假数据 Dummy Byte
      //delay_nop(10);
      for(i = 0; i < BUFSIZE; i++)
      {
                *(buffer + i)      = SPI_READ_BYTE();                                                                //读取字库芯片发送过来的点阵编码
      }

      SPI_CS_ON();                                                                                                               //CS置高,结束本次操作
      delay_nop(10);

      SPI_CLEAR();                                                                                                                //清除SPI总线
      delay_nop(10);
}

/*******************************************************
*函数名称:WORDLIB_read_ASCII_6x12
*函数功能:读取字库芯片中一个ASCII字符的6x12点阵编码
*入口参数:ASCIICode,ASCII码;buffer,点阵编码的缓冲区;
                                 buffer必须大于等于12个字节。
*出口参数:无
******************************************************/
void WORDLIB_read_ASCII_6x12(uint16_t ASCIICode, uint8_t *buffer)
{

      uint32_t BaseAddr      = 0x1DBE00;                                                                              //6x12点阵的起始地址,见手册《GT23L32S4W用户手册》
      uint32_t WordAddr      = 0;                                                                                        //ASCII字符点阵在芯片中的字节地址
      const uint32_t BUFSIZE      = 12;                                                                              //缓冲区的大小
      uint8_t      i;

      //计算地址,见手册《GT23L32S4W用户手册》
      if((ASCIICode >= 0x20) && (ASCIICode <= 0x7E))
      {
                WordAddr      = (ASCIICode - 0x20) * BUFSIZE + BaseAddr;
      }

      SPI_CLEAR();                                                                                                                //清除SPI总线
      delay_nop(10);
      
      //开始快速读取点阵数据:Read Data Bytes At Higher Speed
      SPI_CS_OFF();
      delay_nop(10);
      
      SPI_WRITE_BYTE(CMD_FASTREAD_WORDLIB);                                                                //发送命令字:0x0B
      SPI_WRITE_BYTE((WordAddr >> 16) & 0xff);                                                      //从高到低,依次发送三个字节的地址
      SPI_WRITE_BYTE((WordAddr >> 8) & 0xff);
      SPI_WRITE_BYTE(WordAddr & 0xff);
      SPI_WRITE_BYTE(CMD_DUMMY);                                                                                        //最后发送一个字节的假数据 Dummy Byte
      //delay_nop(10);
      for(i = 0; i < BUFSIZE; i++)
      {
                *(buffer + i)      = SPI_READ_BYTE();                                                                //读取字库芯片发送过来的点阵编码
      }

      SPI_CS_ON();                                                                                                               //CS置高,结束本次操作
      delay_nop(10);

      SPI_CLEAR();                                                                                                                //清除SPI总线
      delay_nop(10);
}

/*******************************************************
*函数名称:WORDLIB_read_ASCII_8x16
*函数功能:读取字库芯片中一个ASCII字符的8x16点阵编码
*入口参数:ASCIICode,ASCII码;buffer,点阵编码的缓冲区;
                                 buffer必须大于等于16个字节。
*出口参数:无
******************************************************/
void WORDLIB_read_ASCII_8x16(uint16_t ASCIICode, uint8_t *buffer)
{

      uint32_t BaseAddr      = 0x1DD780;                                                                              //8x16点阵的起始地址,见手册《GT23L32S4W用户手册》
      uint32_t WordAddr      = 0;                                                                                        //ASCII字符点阵在芯片中的字节地址
      const uint32_t BUFSIZE      = 16;                                                                              //缓冲区的大小
      uint8_t      i;

      //计算地址,见手册《GT23L32S4W用户手册》
      if((ASCIICode >= 0x20) && (ASCIICode <= 0x7E))
      {
                WordAddr      = (ASCIICode - 0x20) * BUFSIZE + BaseAddr;
      }

      SPI_CLEAR();                                                                                                                //清除SPI总线
      delay_nop(10);
      
      //开始快速读取点阵数据:Read Data Bytes At Higher Speed
      SPI_CS_OFF();
      delay_nop(10);
      
      SPI_WRITE_BYTE(CMD_FASTREAD_WORDLIB);                                                                //发送命令字:0x0B
      SPI_WRITE_BYTE((WordAddr >> 16) & 0xff);                                                      //从高到低,依次发送三个字节的地址
      SPI_WRITE_BYTE((WordAddr >> 8) & 0xff);
      SPI_WRITE_BYTE(WordAddr & 0xff);
      SPI_WRITE_BYTE(CMD_DUMMY);                                                                                        //最后发送一个字节的假数据 Dummy Byte
      //delay_nop(10);
      for(i = 0; i < BUFSIZE; i++)
      {
                *(buffer + i)      = SPI_READ_BYTE();                                                                //读取字库芯片发送过来的点阵编码
      }

      SPI_CS_ON();                                                                                                               //CS置高,结束本次操作
      delay_nop(10);

      SPI_CLEAR();                                                                                                                //清除SPI总线
      delay_nop(10);
}

/*******************************************************
*函数名称:WORDLIB_read_ASCII_12x24
*函数功能:读取字库芯片中一个ASCII字符的12x24点阵编码
*入口参数:ASCIICode,ASCII码;buffer,点阵编码的缓冲区;
                                 buffer必须大于等于48个字节。
*出口参数:无
******************************************************/
void WORDLIB_read_ASCII_12x24(uint16_t ASCIICode, uint8_t *buffer)
{
      uint32_t BaseAddr      = 0x1DFF00;                                                                              //12x24点阵的起始地址,见手册《GT23L32S4W用户手册》
      uint32_t WordAddr      = 0;                                                                                        //ASCII字符点阵在芯片中的字节地址
      const uint32_t BUFSIZE      = 48;                                                                              //缓冲区的大小
      uint8_t      i;

      //计算地址,见手册《GT23L32S4W用户手册》
      if((ASCIICode >= 0x20) && (ASCIICode <= 0x7E))
      {
                WordAddr      = (ASCIICode - 0x20) * BUFSIZE + BaseAddr;
      }

      SPI_CLEAR();                                                                                                                //清除SPI总线
      delay_nop(10);
      
      //开始快速读取点阵数据:Read Data Bytes At Higher Speed
      SPI_CS_OFF();
      delay_nop(10);
      
      SPI_WRITE_BYTE(CMD_FASTREAD_WORDLIB);                                                                //发送命令字:0x0B
      SPI_WRITE_BYTE((WordAddr >> 16) & 0xff);                                                      //从高到低,依次发送三个字节的地址
      SPI_WRITE_BYTE((WordAddr >> 8) & 0xff);
      SPI_WRITE_BYTE(WordAddr & 0xff);
      SPI_WRITE_BYTE(CMD_DUMMY);                                                                                        //最后发送一个字节的假数据 Dummy Byte
      //delay_nop(10);
      for(i = 0; i < BUFSIZE; i++)
      {
                *(buffer + i)      = SPI_READ_BYTE();                                                                //读取字库芯片发送过来的点阵编码
      }

      SPI_CS_ON();                                                                                                               //CS置高,结束本次操作
      delay_nop(10);

      SPI_CLEAR();                                                                                                                //清除SPI总线
      delay_nop(10);
}

/*******************************************************
*函数名称:WORDLIB_read_ASCII_16x32
*函数功能:读取字库芯片中一个ASCII字符的16x32点阵编码
*入口参数:ASCIICode,ASCII码;buffer,点阵编码的缓冲区;
                                 buffer必须大于等于64个字节。
*出口参数:无
******************************************************/
void WORDLIB_read_ASCII_16x32(uint16_t ASCIICode, uint8_t *buffer)
{
      uint32_t BaseAddr      = 0x1E5A50;                                                                              //16x32点阵的起始地址,见手册《GT23L32S4W用户手册》
      uint32_t WordAddr      = 0;                                                                                        //ASCII字符点阵在芯片中的字节地址
      const uint32_t BUFSIZE      = 64;                                                                              //缓冲区的大小
      uint8_t      i;

      //计算地址,见手册《GT23L32S4W用户手册》
      if((ASCIICode >= 0x20) && (ASCIICode <= 0x7E))
      {
                WordAddr      = (ASCIICode - 0x20) * BUFSIZE + BaseAddr;
      }

      SPI_CLEAR();                                                                                                                //清除SPI总线
      delay_nop(10);
      
      //开始快速读取点阵数据:Read Data Bytes At Higher Speed
      SPI_CS_OFF();
      delay_nop(10);
      
      SPI_WRITE_BYTE(CMD_FASTREAD_WORDLIB);                                                                //发送命令字:0x0B
      SPI_WRITE_BYTE((WordAddr >> 16) & 0xff);                                                      //从高到低,依次发送三个字节的地址
      SPI_WRITE_BYTE((WordAddr >> 8) & 0xff);
      SPI_WRITE_BYTE(WordAddr & 0xff);
      SPI_WRITE_BYTE(CMD_DUMMY);                                                                                        //最后发送一个字节的假数据 Dummy Byte
      //delay_nop(10);
      for(i = 0; i < BUFSIZE; i++)
      {
                *(buffer + i)      = SPI_READ_BYTE();                                                                //读取字库芯片发送过来的点阵编码
      }

      SPI_CS_ON();                                                                                                               //CS置高,结束本次操作
      delay_nop(10);

      SPI_CLEAR();                                                                                                                //清除SPI总线
      delay_nop(10);
}


/*===============================================国标汉字取码(非扩展等宽字符)===========================================*/
/*******************************************************
*函数名称:WORDLIB_read_GB_12x12
*函数功能:读取字库芯片中一个国标汉字的12x12点阵编码
*入口参数:GBCode,汉字内码;buffer,点阵编码的缓冲区;
                                 buffer必须大于等于24个字节。
*出口参数:无
******************************************************/
void WORDLIB_read_GB_12x12(uint16_t GBCode, uint8_t *buffer)
{
      uint32_t BaseAddr      = 0;                                                                                        //12x12点阵的起始地址,见手册《GT23L32S4W用户手册》
      uint8_t GBCode_MSB      = (GBCode >> 8) & 0xFF;                                                      //汉字内码的高八位
      uint8_t GBCode_LSB      = GBCode & 0xFF;                                                                //汉字内码的低八位
      uint32_t WordAddr      = 0;                                                                                        //汉字点阵在芯片中的字节地址
      const uint32_t BUFSIZE      = 24;                                                                              //缓冲区的大小
      uint8_t      i;

      //计算地址,见手册《GT23L32S4W用户手册》
      if((GBCode_MSB >= 0xA1) && (GBCode_MSB <= 0xA3) && (GBCode_LSB >= 0xA1))
      {
                WordAddr      = ((GBCode_MSB - 0xA1) * 94 + (GBCode_LSB - 0xA1)) * BUFSIZE + BaseAddr;
      }
      else if((GBCode_MSB == 0xA9) &&      (GBCode_LSB >= 0xA1))
      {
                WordAddr      = (282 + (GBCode_LSB - 0xA1)) * BUFSIZE + BaseAddr;
      }
      else if((GBCode_MSB >= 0xB0) && (GBCode_MSB <= 0xF7) &&      (GBCode_LSB >= 0xA1))
      {
                WordAddr      = ((GBCode_MSB - 0xB0) * 94 + (GBCode_LSB - 0xA1) + 846) * BUFSIZE + BaseAddr;
      }

      SPI_CLEAR();                                                                                                                //清除SPI总线
      delay_nop(10);
      
      //开始快速读取点阵数据:Read Data Bytes At Higher Speed
      SPI_CS_OFF();
      delay_nop(10);
      
      SPI_WRITE_BYTE(CMD_FASTREAD_WORDLIB);                                                                //发送命令字:0x0B
      SPI_WRITE_BYTE((WordAddr >> 16) & 0xff);                                                      //从高到低,依次发送三个字节的地址
      SPI_WRITE_BYTE((WordAddr >> 8) & 0xff);
      SPI_WRITE_BYTE(WordAddr & 0xff);
      SPI_WRITE_BYTE(CMD_DUMMY);                                                                                        //最后发送一个字节的假数据 Dummy Byte
      //delay_nop(10);
      for(i = 0; i < BUFSIZE; i++)
      {
                *(buffer + i)      = SPI_READ_BYTE();                                                                //读取字库芯片发送过来的点阵编码
      }

      SPI_CS_ON();                                                                                                               //CS置高,结束本次操作
      delay_nop(10);

      SPI_CLEAR();                                                                                                                //清除SPI总线
      delay_nop(10);
}

/*******************************************************
*函数名称:WORDLIB_read_GB_16x16
*函数功能:读取字库芯片中一个国标汉字的16x16点阵编码
*入口参数:GBCode,汉字内码;buffer,点阵编码的缓冲区;
                                 buffer必须大于等于32个字节。
*出口参数:无
******************************************************/
void WORDLIB_read_GB_16x16(uint16_t GBCode, uint8_t *buffer)
{
      uint32_t BaseAddr      = 0x2C9D0;                                                                              //16x16点阵的起始地址,见手册《GT23L32S4W用户手册》
      uint8_t GBCode_MSB      = (GBCode >> 8) & 0xFF;                                                      //汉字内码的高八位
      uint8_t GBCode_LSB      = GBCode & 0xFF;                                                                //汉字内码的低八位
      uint32_t WordAddr      = 0;                                                                                        //汉字或者ASCII字符点阵在芯片中的字节地址
      const uint32_t BUFSIZE      = 32;                                                                              //缓冲区的大小
      uint8_t      i;

      //计算地址,见手册《GT23L32S4W用户手册》
      if((GBCode_MSB >= 0xA4) && (GBCode_MSB <= 0xA8) && (GBCode_LSB >= 0xA1))
      {
                WordAddr      = BaseAddr;
      }
      else if((GBCode_MSB >= 0xA1) && (GBCode_MSB <= 0xA9) &&      (GBCode_LSB >= 0xA1))
      {
                WordAddr      = ((GBCode_MSB - 0xA1) * 94 + (GBCode_LSB - 0xA1)) * BUFSIZE + BaseAddr;
      }
      else if((GBCode_MSB >= 0xB0) && (GBCode_MSB <= 0xF7) &&      (GBCode_LSB >= 0xA1))
      {
                WordAddr      = ((GBCode_MSB - 0xB0) * 94 + (GBCode_LSB - 0xA1) + 846) * BUFSIZE + BaseAddr;
      }

      SPI_CLEAR();                                                                                                                //清除SPI总线
      delay_nop(10);
      
      //开始快速读取点阵数据:Read Data Bytes At Higher Speed
      SPI_CS_OFF();
      delay_nop(10);
      
      SPI_WRITE_BYTE(CMD_FASTREAD_WORDLIB);                                                                //发送命令字:0x0B
      SPI_WRITE_BYTE((WordAddr >> 16) & 0xff);                                                      //从高到低,依次发送三个字节的地址
      SPI_WRITE_BYTE((WordAddr >> 8) & 0xff);
      SPI_WRITE_BYTE(WordAddr & 0xff);
      SPI_WRITE_BYTE(CMD_DUMMY);                                                                                        //最后发送一个字节的假数据 Dummy Byte
      //delay_nop(10);
      for(i = 0; i < BUFSIZE; i++)
      {
                *(buffer + i)      = SPI_READ_BYTE();                                                                //读取字库芯片发送过来的点阵编码
      }

      SPI_CS_ON();                                                                                                               //CS置高,结束本次操作
      delay_nop(10);

      SPI_CLEAR();                                                                                                                //清除SPI总线
      delay_nop(10);
}

/*******************************************************
*函数名称:WORDLIB_read_GB_24x24
*函数功能:读取字库芯片中一个国标汉字的24x24点阵编码
*入口参数:GBCode,汉字内码;buffer,点阵编码的缓冲区;
                                 buffer必须大于等于72个字节。
*出口参数:无
******************************************************/
void WORDLIB_read_GB_24x24(uint16_t GBCode, uint8_t *buffer)
{

      uint32_t BaseAddr      = 0x68190;                                                                              //24x24点阵的起始地址,见手册《GT23L32S4W用户手册》
      uint8_t GBCode_MSB      = (GBCode >> 8) & 0xFF;                                                      //汉字内码的高八位
      uint8_t GBCode_LSB      = GBCode & 0xFF;                                                                //汉字内码的低八位
      uint32_t WordAddr      = 0;                                                                                        //汉字或者ASCII字符点阵在芯片中的字节地址
      const uint32_t BUFSIZE      = 72;                                                                              //缓冲区的大小
      uint8_t      i;

      //计算地址,见手册《GT23L32S4W用户手册》
      if((GBCode_MSB >= 0xA4) && (GBCode_MSB <= 0xA8) && (GBCode_LSB >= 0xA1))
      {
                WordAddr      = BaseAddr;
      }
      else if((GBCode_MSB >= 0xA1) && (GBCode_MSB <= 0xA9) &&      (GBCode_LSB >= 0xA1))
      {
                WordAddr      = ((GBCode_MSB - 0xA1) * 94 + (GBCode_LSB - 0xA1)) * BUFSIZE + BaseAddr;
      }
      else if((GBCode_MSB >= 0xB0) && (GBCode_MSB <= 0xF7) &&      (GBCode_LSB >= 0xA1))
      {
                WordAddr      = ((GBCode_MSB - 0xB0) * 94 + (GBCode_LSB - 0xA1) + 846) * BUFSIZE + BaseAddr;
      }

      SPI_CLEAR();                                                                                                                //清除SPI总线
      delay_nop(10);
      
      //开始快速读取点阵数据:Read Data Bytes At Higher Speed
      SPI_CS_OFF();
      delay_nop(10);
      
      SPI_WRITE_BYTE(CMD_FASTREAD_WORDLIB);                                                                //发送命令字:0x0B
      SPI_WRITE_BYTE((WordAddr >> 16) & 0xff);                                                      //从高到低,依次发送三个字节的地址
      SPI_WRITE_BYTE((WordAddr >> 8) & 0xff);
      SPI_WRITE_BYTE(WordAddr & 0xff);
      SPI_WRITE_BYTE(CMD_DUMMY);                                                                                        //最后发送一个字节的假数据 Dummy Byte
      //delay_nop(10);
      for(i = 0; i < BUFSIZE; i++)
      {
                *(buffer + i)      = SPI_READ_BYTE();                                                                //读取字库芯片发送过来的点阵编码
      }

      SPI_CS_ON();                                                                                                               //CS置高,结束本次操作
      delay_nop(10);

      SPI_CLEAR();                                                                                                                //清除SPI总线
      delay_nop(10);
}

/*******************************************************
*函数名称:WORDLIB_read_GB_32x32
*函数功能:读取字库芯片中一个国标汉字的32x32点阵编码
*入口参数:GBCode,汉字内码;buffer,点阵编码的缓冲区;
                                 buffer必须大于等于128个字节。
*出口参数:无
******************************************************/
void WORDLIB_read_GB_32x32(uint16_t GBCode, uint8_t *buffer)
{
      uint32_t BaseAddr      = 0xEDF00;                                                                              //32x32点阵的起始地址,见手册《GT23L32S4W用户手册》
      uint8_t GBCode_MSB      = (GBCode >> 8) & 0xFF;                                                      //汉字内码的高八位
      uint8_t GBCode_LSB      = GBCode & 0xFF;                                                                //汉字内码的低八位
      uint32_t WordAddr      = 0;                                                                                        //汉字或者ASCII字符点阵在芯片中的字节地址
      const uint32_t BUFSIZE      = 128;                                                                              //缓冲区的大小
      uint8_t      i;

      //计算地址,见手册《GT23L32S4W用户手册》
      if((GBCode_MSB >= 0xA4) && (GBCode_MSB <= 0xA8) && (GBCode_LSB >= 0xA1))
      {
                WordAddr      = BaseAddr;
      }
      else if((GBCode_MSB >= 0xA1) && (GBCode_MSB <= 0xA9) &&      (GBCode_LSB >= 0xA1))
      {
                WordAddr      = ((GBCode_MSB - 0xA1) * 94 + (GBCode_LSB - 0xA1)) * BUFSIZE + BaseAddr;
      }
      else if((GBCode_MSB >= 0xB0) && (GBCode_MSB <= 0xF7) &&      (GBCode_LSB >= 0xA1))
      {
                WordAddr      = ((GBCode_MSB - 0xB0) * 94 + (GBCode_LSB - 0xA1) + 846) * BUFSIZE + BaseAddr;
      }

      SPI_CLEAR();                                                                                                                //清除SPI总线
      delay_nop(10);
      
      //开始快速读取点阵数据:Read Data Bytes At Higher Speed
      SPI_CS_OFF();
      delay_nop(10);
      
      SPI_WRITE_BYTE(CMD_FASTREAD_WORDLIB);                                                                //发送命令字:0x0B
      SPI_WRITE_BYTE((WordAddr >> 16) & 0xff);                                                      //从高到低,依次发送三个字节的地址
      SPI_WRITE_BYTE((WordAddr >> 8) & 0xff);
      SPI_WRITE_BYTE(WordAddr & 0xff);
      SPI_WRITE_BYTE(CMD_DUMMY);                                                                                        //最后发送一个字节的假数据 Dummy Byte
      //delay_nop(10);
      for(i = 0; i < BUFSIZE; i++)
      {
                *(buffer + i)      = SPI_READ_BYTE();                                                                //读取字库芯片发送过来的点阵编码
      }

      SPI_CS_ON();                                                                                                               //CS置高,结束本次操作
      delay_nop(10);

      SPI_CLEAR();                                                                                                                //清除SPI总线
      delay_nop(10);
}

延时函数:
void delay_nop(unsigned int uiDelayNop)
{
      
      while(uiDelayNop!=0)
      {
                uiDelayNop--;
      }
               
}




页: [1]
查看完整版本: 使用STM32F103VB芯片模拟SPI时序读取字库芯片GT30L32S4W