测试使用I2C硬件方式驱动OLED显示屏。
一、硬件接口
驱动OLED显示屏,使用i2c1,使用到PB6和PB7,在软件中配置端口。
二、程序部分
2.1、oled.c
#include "at32l021.h"
#include "oled/oled.h"
#include "oled/codetab.h"
#include "delay/delay.h"
#include "i2c/i2c.h"
#include "i2c_application.h"
void I2C_WriteByte(uint8_t addr, uint8_t dat)
{
uint8_t temp[2];
temp[0] = addr;
temp[1] = dat;
i2c_senddat(OLED_ADDRESS, temp, 2);
}
void WriteCmd(unsigned char I2C_Command)
{
I2C_WriteByte(0x00, I2C_Command);
}
void WriteDat(unsigned char I2C_Data)
{
I2C_WriteByte(0x40, I2C_Data);
}
void OLED_WrCmd(unsigned char IIC_Command)
{
WriteCmd(IIC_Command);
}
void OLED_Init(void)
{
delay_ms(100);
WriteCmd(0xAE); //display off
WriteCmd(0x20); //Set Memory Addressing Mode
WriteCmd(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
WriteCmd(0xb0); //Set Page Start Address for Page Addressing Mode,0-7
WriteCmd(0xc8); //Set COM Output Scan Direction
WriteCmd(0x00); //---set low column address
WriteCmd(0x10); //---set high column address
WriteCmd(0x40); //--set start line address
WriteCmd(0x81); //--set contrast control register
WriteCmd(0xff); //亮度调节 0x00~0xff
WriteCmd(0xa1); //--set segment re-map 0 to 127
WriteCmd(0xa6); //--set normal display
WriteCmd(0xa8); //--set multiplex ratio(1 to 64)
WriteCmd(0x3F); //
WriteCmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
WriteCmd(0xd3); //-set display offset
WriteCmd(0x00); //-not offset
WriteCmd(0xd5); //--set display clock divide ratio/oscillator frequency
WriteCmd(0xf0); //--set divide ratio
WriteCmd(0xd9); //--set pre-charge period
WriteCmd(0x22); //
WriteCmd(0xda); //--set com pins hardware configuration
WriteCmd(0x12);
WriteCmd(0xdb); //--set vcomh
WriteCmd(0x40); //0x20,0.77xVcc
WriteCmd(0x8d); //--set DC-DC enable
WriteCmd(0x14); //
WriteCmd(0xaf); //--turn on oled panel
}
void OLED_SetPos(unsigned char x, unsigned char y)
{
WriteCmd(0xb0+y);
WriteCmd(((x&0xf0)>>4)|0x10);
WriteCmd((x&0x0f)|0x01);
}
void OLED_Fill(unsigned char fill_Data)//全屏填充
{
unsigned char m,n;
for(m=0;m<8;m++)
{
WriteCmd(0xb0+m); //page0-page1
WriteCmd(0x00); //low column start address
WriteCmd(0x10); //high column start address
for(n=0;n<128;n++)
{
WriteDat(fill_Data);
}
}
}
void OLED_CLS(void)//清屏
{
OLED_Fill(0xff);
}
void OLED_ON(void)
{
WriteCmd(0X8D); //设置电荷泵
WriteCmd(0X14); //开启电荷泵
WriteCmd(0XAF); //OLED唤醒
}
void OLED_OFF(void)
{
WriteCmd(0X8D); //设置电荷泵
WriteCmd(0X10); //关闭电荷泵
WriteCmd(0XAE); //OLED休眠
}
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize)
{
unsigned char c = 0,i = 0,j = 0;
switch(TextSize)
{
case 1:
{
while(ch[j] != '\0')
{
c = ch[j] - 32;
if(x > 126)
{
x = 0;
y++;
}
OLED_SetPos(x,y);
for(i=0;i<6;i++)
WriteDat(F6x8[c][i]);
x += 6;
j++;
}
}break;
case 2:
{
while(ch[j] != '\0')
{
c = ch[j] - 32;
if(x > 120)
{
x = 0;
y++;
}
OLED_SetPos(x,y);
for(i=0;i<8;i++)
WriteDat(F8X16[c*16+i]);
OLED_SetPos(x,y+1);
for(i=0;i<8;i++)
WriteDat(F8X16[c*16+i+8]);
x += 8;
j++;
}
}break;
}
}
void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
{
unsigned char wm=0;
unsigned int adder=32*N;
OLED_SetPos(x , y);
for(wm = 0;wm < 16;wm++)
{
WriteDat(F16x16[adder]);
adder += 1;
}
OLED_SetPos(x,y + 1);
for(wm = 0;wm < 16;wm++)
{
WriteDat(F16x16[adder]);
adder += 1;
}
}
void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[])
{
unsigned int j=0;
unsigned char x,y;
if(y1%8==0)
y = y1/8;
else
y = y1/8 + 1;
for(y=y0;y<y1;y++)
{
OLED_SetPos(x0,y);
for(x=x0;x<x1;x++)
{
WriteDat(BMP[j++]);
}
}
}
void oled_test(void)
{
OLED_Init();
OLED_Fill(0x00);
OLED_ShowStr(0,0,"AT32L021 BOARD",2);
OLED_ShowStr(0,2,"I2C OLED TEST",2);
}
2.2、i2c.c
#include "at32l021.h"
#include "i2c/i2c.h"
#include "i2c_application.h"
i2c_handle_type hi2cx;
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] initializes peripherals used by the i2c.
* @param none
* @retval none
*/
void i2c_lowlevel_init(i2c_handle_type* hi2c)
{
gpio_init_type gpio_init_structure;
if(hi2c->i2cx == I2Cx_PORT)
{
/* i2c periph clock enable */
crm_periph_clock_enable(I2Cx_CLK, TRUE);
crm_periph_clock_enable(I2Cx_SCL_GPIO_CLK, TRUE);
crm_periph_clock_enable(I2Cx_SDA_GPIO_CLK, TRUE);
/* gpio configuration */
gpio_pin_mux_config(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_GPIO_PinsSource, I2Cx_SCL_GPIO_MUX);
gpio_pin_mux_config(I2Cx_SDA_GPIO_PORT, I2Cx_SDA_GPIO_PinsSource, I2Cx_SDA_GPIO_MUX);
/* configure i2c pins: scl */
gpio_init_structure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_structure.gpio_mode = GPIO_MODE_MUX;
gpio_init_structure.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN;
gpio_init_structure.gpio_pull = GPIO_PULL_NONE;
gpio_init_structure.gpio_pins = I2Cx_SCL_GPIO_PIN;
gpio_init(I2Cx_SCL_GPIO_PORT, &gpio_init_structure);
/* configure i2c pins: sda */
gpio_init_structure.gpio_pins = I2Cx_SDA_GPIO_PIN;
gpio_init(I2Cx_SDA_GPIO_PORT, &gpio_init_structure);
/* config i2c */
i2c_init(hi2c->i2cx, 0x0F, I2Cx_CLKCTRL);
i2c_own_address1_set(hi2c->i2cx, I2C_ADDRESS_MODE_7BIT, I2Cx_ADDRESS);
}
}
void init_i2c(void){
hi2cx.i2cx = I2Cx_PORT;
i2c_config(&hi2cx);
}
void i2c_senddat(uint16_t address, uint8_t* pdata, uint16_t size)
{
i2c_master_transmit(&hi2cx, address, pdata, size, I2C_TIMEOUT);
}
2.3、main.c
#include "at32l021_clock.h"
#include "led/led.h"
#include "delay/delay.h"
#include "i2c/i2c.h"
#include "oled/oled.h"
int main(void)
{
system_clock_config();
delay_init();
init_led();
init_i2c();
OLED_Init();
oled_test();
while(1)
{
led2_tog();
delay_ms(200);
led3_tog();
delay_ms(200);
led4_tog();
delay_ms(200);
}
}
三、程序运行
下载程序后,OLED显示屏显示内容
|
|