#include "gd32f30x.h"
#include "gd32f307c_eval.h"
#include "systick.h"
#include "oled.h"
#define CS_Clr() gpio_bit_reset(GPIOA,GPIO_PIN_4) //cs PA4
#define CS_Set() gpio_bit_set(GPIOA,GPIO_PIN_4)
#define DC_Clr() gpio_bit_reset(GPIOB,GPIO_PIN_1) //dc PB1
#define DC_Set() gpio_bit_set(GPIOB,GPIO_PIN_1)
#define RST_Clr() gpio_bit_reset(GPIOB,GPIO_PIN_0) //RES PB0
#define RST_Set() gpio_bit_set(GPIOB,GPIO_PIN_0)
uint8_t SPI_TX_BUF[4] = {0x9F,0xFF,0xFF,0xFF};
uint8_t spi0_receive_array[ARRAYSIZE];
uint16_t le1=1;
uint16_t sj1[2]={0xB1,0x22};
uint8_t Parameter=1;
uint8_t Command=0;
void DMASPI0_config(void) //DMA
{
rcu_periph_clock_enable(RCU_DMA0);
dma_parameter_struct dma_init_struct;
/* SPI0 transmit dma config:DMA0-DMA_CH2 */
dma_deinit(DMA0, DMA_CH2);
dma_init_struct.periph_addr = (uint32_t)(&SPI_DATA(SPI0));
dma_init_struct.memory_addr = (uint32_t)SPI_TX_BUF; //发送的数据地址,定义一个数组
dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL; //内存搬到外设
dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
dma_init_struct.priority = DMA_PRIORITY_LOW;
dma_init_struct.number = ARRAYSIZE; //发送的字符数据个数,(0x02,0x25)就是2个数据
dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_init(DMA0, DMA_CH2, &dma_init_struct);
/* configure DMA mode */
dma_circulation_disable(DMA0, DMA_CH2);
dma_memory_to_memory_disable(DMA0, DMA_CH2);
dma_channel_enable(DMA0, DMA_CH2);
}
void spi_config(void) //初始化spi0
{
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_GPIOC);
rcu_periph_clock_enable(RCU_AF);
rcu_periph_clock_enable(RCU_SPI1);
spi_parameter_struct spi_init_struct;
/* deinitilize SPI and the parameters */
spi_struct_para_init(&spi_init_struct);
/* SPI0 parameter config */
spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX; // 全双工模式 SPI_TRANSMODE_BDTRANSMIT SPI_TRANSMODE_FULLDUPLEX
spi_init_struct.device_mode = SPI_MASTER; // 主机模式
spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT; // spi使用8位数据帧格式
spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_1EDGE; // 在spi为空闲状态时,clk时钟引脚拉低,时钟的第二个跳变沿开始采集数据 SPI_CK_PL_HIGH_PH_2EDGE
spi_init_struct.nss = SPI_NSS_SOFT;
spi_init_struct.prescale = SPI_PSC_8; //分频设置108/8=13.5m
spi_init_struct.endian = SPI_ENDIAN_MSB; // 先发送最高位
spi_init(SPI0, &spi_init_struct); // 使用spi_init_struct结构参数初始化spi0
spi_crc_polynomial_set(SPI1,7); // 把7写入主机的crc多项式寄存器
spi_enable(SPI0); // 使能spi
}
void gpio_config(void)
{
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOB);
/* SPI0 GPIO config: SCK/PA5, MISO/PA6, MOSI/PA7 */
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5 | GPIO_PIN_7);
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
/* PA4 as cs片选 pb0是reset,pb1是d/c*/
gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4);
gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0| GPIO_PIN_1);
RST_Set();
}
void LCD_Writ_Bus(uint8_t dat)
{
CS_Clr();
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE));
spi_i2s_data_transmit(SPI0, dat);
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE));
spi_i2s_data_receive(SPI0);
// DMASPI0_write_8(&dat,1); 现在是硬件spi,如果将这行取消注释并把上面四行注释就切换成了spi+dma,这时DC引脚就会时序不正常
CS_Set();
}
void LCD_WR_DATA8(uint8_t dat)
{
DC_Set();//Write data
LCD_Writ_Bus(dat);
//DMASPI0_write((uint16_t*)dat,1);
}
void LCD_WR_DATA(uint16_t dat)
{
LCD_Writ_Bus(dat>>8);
LCD_Writ_Bus(dat);
}
void LCD_WR_REG(uint8_t dat)
{
DC_Clr();//Write command
LCD_Writ_Bus(dat);
// DMASPI0_write((uint16_t*)dat,1);
DC_Set();//Write data
}
void DMASPI0_write(uint16_t *buf, uint16_t size) //DMA write
{
dma_channel_disable(DMA0,DMA_CH2);
dma_memory_address_config(DMA0,DMA_CH2,(uint32_t)buf);
dma_transfer_number_config(DMA0,DMA_CH2,size);
dma_channel_enable(DMA0,DMA_CH2);
}
void DMASPI0_write_8(uint8_t *buf, uint16_t len) //DMA write
{
dma_channel_disable(DMA0,DMA_CH2);
dma_memory_address_config(DMA0,DMA_CH2,(uint32_t)buf);
dma_transfer_number_config(DMA0,DMA_CH2,len);
spi_dma_enable(SPI0, SPI_DMA_TRANSMIT);
//spi_dma_enable(SPI0, SPI_DMA_RECEIVE);
dma_channel_enable(DMA0, DMA_CH2);
while(!dma_flag_get(DMA0,DMA_CH2, DMA_INTF_FTFIF)) {
}
}
void oled_write(uint8_t dc,uint8_t sj)
{
uint8_t sj1[1]={sj};
if (dc==0)
DC_Clr();
else
DC_Set();
// DMASPI0_write_8(sj1,1);
}
void oled_write_16(uint16_t dat)
{
DC_Set();
uint16_t a=dat>>8,b=dat&0x00FF;
uint16_t dk[2]={a,b};
DMASPI0_write(dk,2);
}
void oled_write_8(uint8_t db)
{
uint16_t dt[1]={db};
DC_Set();
DMASPI0_write(dt,1);
}
void oled_init(void)
{
//gpio_config();
RST_Set();
delay_1ms(10);
RST_Clr();
delay_1ms(10);
RST_Set();;
delay_1ms(120);
LCD_WR_REG(0x11);
delay_1ms(120);
LCD_WR_REG(0x36);
LCD_WR_DATA8( 0x00); //RGB
LCD_WR_REG(0x3A);
LCD_WR_DATA8(0x05); //16BIT
LCD_WR_REG(0xB2);
LCD_WR_DATA8(0x05);
LCD_WR_DATA8(0x05);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x33);
LCD_WR_DATA8(0x33);
LCD_WR_REG(0xB7);
LCD_WR_DATA8(0x35);
LCD_WR_REG(0xBB);
LCD_WR_DATA8(0x21);
LCD_WR_REG(0xC0);
LCD_WR_DATA8(0x2C);
LCD_WR_REG(0xC2);
LCD_WR_DATA8(0x01);
LCD_WR_REG(0xC3);
LCD_WR_DATA8(0x0B);
LCD_WR_REG(0xC4);
LCD_WR_DATA8(0x20);
LCD_WR_REG(0xC6);
LCD_WR_DATA8(0x0F); //60HZ dot inversion
LCD_WR_REG(0xD0);
LCD_WR_DATA8(0xA7);
LCD_WR_DATA8(0xA1);
LCD_WR_REG( 0xD0);
LCD_WR_DATA8(0xA4);
LCD_WR_DATA8(0xA1);
LCD_WR_REG( 0xD6);
LCD_WR_DATA8(0xA1);
LCD_WR_REG(0xE0);
LCD_WR_DATA8(0xD0);
LCD_WR_DATA8(0x04);
LCD_WR_DATA8(0x08);
LCD_WR_DATA8(0x0A);
LCD_WR_DATA8(0x09);
LCD_WR_DATA8(0x05);
LCD_WR_DATA8(0x2D);
LCD_WR_DATA8(0x43);
LCD_WR_DATA8(0x49);
LCD_WR_DATA8(0x09);
LCD_WR_DATA8(0x16);
LCD_WR_DATA8(0x15);
LCD_WR_DATA8(0x26);
LCD_WR_DATA8(0x2B);
LCD_WR_REG( 0xE1);
LCD_WR_DATA8(0xD0);
LCD_WR_DATA8(0x03);
LCD_WR_DATA8(0x09);
LCD_WR_DATA8(0x0A);
LCD_WR_DATA8(0x0A);
LCD_WR_DATA8(0x06);
LCD_WR_DATA8(0x2E);
LCD_WR_DATA8(0x44);
LCD_WR_DATA8(0x40);
LCD_WR_DATA8(0x3A);
LCD_WR_DATA8(0x15);
LCD_WR_DATA8(0x15);
LCD_WR_DATA8(0x26);
LCD_WR_DATA8(0x2A);
LCD_WR_REG(0x21);
LCD_WR_REG(0x29);
delay_1ms(10);
LCD_WR_REG(0x2A); //Column Address Set
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x00); //0
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0xEF); //239
LCD_WR_REG(0x2B); //Row Address Set
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x00); //0
LCD_WR_DATA8(0x01);
LCD_WR_DATA8(0x3F); //319
LCD_WR_REG(0x2C);
LCD_WR_REG(0x11);
LCD_WR_REG(0x04);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x00);
delay_1ms(120);
//oled_write(Parameter,0xFF);
//oled_write(Parameter,0xE0);
//oled_write_16(0xFFFF);
LCD_Clear(BLUE) ;
LCD_Clear(RED) ;
LCD_Clear(BLACK) ;
LCD_Clear(WHITE) ;
LCD_Clear(YELLOW) ;
//oled_write(Command ,0x29);
// oled_write_16(0x07FF);
//oled_write(0xffff,1);
}
/********LCD 清屏功能********/
void LCD_Clear(uint16_t Color)
{
uint16_t i,j;
LCD_Address_Set(0,0,LCD_W-1,LCD_H-1);
for(i=0;i<LCD_W;i++)
{
for (j=0;j<LCD_H;j++)
{
LCD_WR_DATA(Color);
}
}
}
//功能描述:设置开始和结束地址
//条目数据:x1、x2 设置列的开始和结束地址
// y1, y2 设置行的始始和结束地址
void LCD_Address_Set(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2)
{
LCD_WR_REG(0x2a); //列地址
LCD_WR_DATA(x1+0);
LCD_WR_DATA(x2+0);
LCD_WR_REG(0x2b); //行地址设定
LCD_WR_DATA(y1+0);
LCD_WR_DATA(y2+0);
LCD_WR_REG(0x2c); //写入屏幕内存
}
|