古人与:工欲善其事,必先利其器
一、新建工程
请看这个帖子: https://www.iceasy.com/review/1894585782601457665
二、硬件连接
咱这个V2版本的可以直接使用USB下载了,不需要额外的串口助手
OLED -------> 开发板
VCC --------> VCC
SCL --------> PB3
SDA --------> PB4
GND --------> GND
三、代码
void oled_i2c_delay(void)
{
uint8_t i = 0;
//for(i = 0; i<5;i++);
}
//���Ժ���
void OLED_ColorTurn( u8 i )
{
if( i == 0 )
{
OLED_WR_Byte( 0xA6, OLED_CMD ); //������ʾ
}
if( i == 1 )
{
OLED_WR_Byte( 0xA7, OLED_CMD ); //��ɫ��ʾ
}
}
//��Ļ��ת180��
void OLED_DisplayTurn( u8 i )
{
if( i == 0 )
{
OLED_WR_Byte( 0xC8, OLED_CMD ); //������ʾ
OLED_WR_Byte( 0xA1, OLED_CMD );
}
if( i == 1 )
{
OLED_WR_Byte( 0xC0, OLED_CMD ); //��ת��ʾ
OLED_WR_Byte( 0xA0, OLED_CMD );
}
}
void OLED_SDIN_Set(void)
{
gpio_bit_set(GPIOB,GPIO_PIN_4);
//GPIO_BOP(GPIOB) = GPIO_PIN_4;
oled_i2c_delay();
}
void OLED_SDIN_Clr(void)
{
gpio_bit_reset(GPIOB,GPIO_PIN_4);
//GPIO_BC(GPIOB) = GPIO_PIN_4;
oled_i2c_delay();
}
void OLED_SCLK_Set(void)
{
gpio_bit_set(GPIOB,GPIO_PIN_3);
//GPIO_BOP(GPIOB) = GPIO_PIN_3;
oled_i2c_delay();
}
void OLED_SCLK_Clr(void)
{
gpio_bit_reset(GPIOB,GPIO_PIN_3);
//GPIO_BC(GPIOB) = GPIO_PIN_3;
oled_i2c_delay();
}
//��ʼ�ź�
void I2C_Start( void )
{
OLED_SDIN_Set();
OLED_SCLK_Set();
OLED_SDIN_Clr();
OLED_SCLK_Clr();
}
//�����ź�
void I2C_Stop( void )
{
OLED_SCLK_Set();
OLED_SDIN_Clr();
OLED_SDIN_Set();
}
//�ȴ��ź���Ӧ
void I2C_WaitAck( void ) //�������źŵĵ�ƽ
{
OLED_SCLK_Set();
OLED_SCLK_Clr();
}
//д��һ���ֽ�
void Send_Byte( u8 dat )
{
u8 i;
for( i = 0; i < 8; i++ )
{
OLED_SCLK_Clr();//��ʱ���ź�����Ϊ�͵�ƽ
if( dat & 0x80 ) //��dat��8λ�����λ����д��
{
OLED_SDIN_Set();
}
else
{
OLED_SDIN_Clr();
}
OLED_SCLK_Set();//��ʱ���ź�����Ϊ�ߵ�ƽ
OLED_SCLK_Clr();//��ʱ���ź�����Ϊ�͵�ƽ
dat <<= 1;
}
}
//����һ���ֽ�
//��SSD1306д��һ���ֽڡ�
//mode:����/�����־ 0,��ʾ����;1,��ʾ����;
void OLED_WR_Byte( u8 dat, u8 mode )
{
I2C_Start();
Send_Byte( 0x78 );
I2C_WaitAck();
if( mode )
{
Send_Byte( 0x40 );
}
else
{
Send_Byte( 0x00 );
}
I2C_WaitAck();
Send_Byte( dat );
I2C_WaitAck();
I2C_Stop();
}
//����OLED��ʾ
void OLED_DisPlay_On( void )
{
OLED_WR_Byte( 0x8D, OLED_CMD ); //��ɱ�ʹ��
OLED_WR_Byte( 0x14, OLED_CMD ); //������ɱ�
OLED_WR_Byte( 0xAF, OLED_CMD ); //������Ļ
}
//�ر�OLED��ʾ
void OLED_DisPlay_Off( void )
{
OLED_WR_Byte( 0x8D, OLED_CMD ); //��ɱ�ʹ��
OLED_WR_Byte( 0x10, OLED_CMD ); //�رյ�ɱ�
OLED_WR_Byte( 0xAF, OLED_CMD ); //�ر���Ļ
}
//�����Դ浽OLED
void OLED_Refresh( void )
{
u8 i, n;
for( i = 0; i < 8; i++ )
{
OLED_WR_Byte( 0xb0 + i, OLED_CMD ); //��������ʼ��ַ
OLED_WR_Byte( 0x00, OLED_CMD ); //���õ�����ʼ��ַ
OLED_WR_Byte( 0x10, OLED_CMD ); //���ø�����ʼ��ַ
for( n = 0; n < 128; n++ )
OLED_WR_Byte( OLED_GRAM[n][i], OLED_DATA );
}
}
//��������
void OLED_Clear( void )
{
u8 i, n;
for( i = 0; i < 8; i++ )
{
for( n = 0; n < 128; n++ )
{
OLED_GRAM[n][i] = 0; //�����������
}
}
OLED_Refresh();//������ʾ
}
//����
//x:0~127
//y:0~63
void OLED_DrawPoint( u8 x, u8 y ,u8 mode)
{
u8 i, m, n;
i = y / 8;
m = y % 8;
n = 1 << m;
if(mode)OLED_GRAM[x][i] |= n;
else OLED_GRAM[x][i] &= ~n;
}
//���һ����
//x:0~127
//y:0~63
void OLED_ClearPoint( u8 x, u8 y )
{
u8 i, m, n;
i = y / 8;
m = y % 8;
n = 1 << m;
OLED_GRAM[x][i] = ~OLED_GRAM[x][i];
OLED_GRAM[x][i] |= n;
OLED_GRAM[x][i] = ~OLED_GRAM[x][i];
}
//����
//x:0~128
//y:0~64
void OLED_DrawLine( u8 x1, u8 y1, u8 x2, u8 y2 )
{
u8 i, k, k1, k2, y0;
if( ( x1 < 0 ) || ( x2 > 128 ) || ( y1 < 0 ) || ( y2 > 64 ) || ( x1 > x2 ) || ( y1 > y2 ) )return;
if( x1 == x2 ) //������
{
for( i = 0; i < ( y2 - y1 ); i++ )
{
OLED_DrawPoint( x1, y1 + i ,1);
}
}
else if( y1 == y2 ) //������
{
for( i = 0; i < ( x2 - x1 ); i++ )
{
OLED_DrawPoint( x1 + i, y1 ,1);
}
}
else //���
{
k1 = y2 - y1;
k2 = x2 - x1;
k = k1 * 10 / k2;
for( i = 0; i < ( x2 - x1 ); i++ )
{
OLED_DrawPoint( x1 + i, y1 + i * k / 10 ,1);
}
}
}
//x,y:Բ������
//r:Բ�İ뾶
void OLED_DrawCircle( u8 x, u8 y, u8 r )
{
int a, b, num;
a = 0;
b = r;
while( 2 * b * b >= r * r )
{
OLED_DrawPoint( x + a, y - b ,1);
OLED_DrawPoint( x - a, y - b ,1);
OLED_DrawPoint( x - a, y + b ,1);
OLED_DrawPoint( x + a, y + b ,1);
OLED_DrawPoint( x + b, y + a ,1);
OLED_DrawPoint( x + b, y - a ,1);
OLED_DrawPoint( x - b, y - a ,1);
OLED_DrawPoint( x - b, y + a ,1);
a++;
num = ( a * a + b * b ) - r * r; //���㻭�ĵ���Բ�ĵľ���
if( num > 0 )
{
b--;
a--;
}
}
}
//��ָ��λ����ʾһ���ַ�,���������ַ�
//x:0~127
//y:0~63
//size:ѡ������ 12/16/24
void OLED_ShowChar( u8 x, u8 y, u8 chr, u8 size1 , u8 mode)
{
u8 i, m, temp, size2, chr1;
u8 y0 = y;
size2 = ( size1 / 8 + ( ( size1 % 8 ) ? 1 : 0 ) ) * ( size1 / 2 ); //�õ�����һ���ַ���Ӧ������ռ���ֽ���
chr1 = chr - ' '; //����ƫ�ƺ��ֵ
for( i = 0; i < size2; i++ )
{
if( size1 == 12 )
{
temp = asc2_1206[chr1][i]; //����1206����
}
else if( size1 == 16 )
{
temp = asc2_1608[chr1][i]; //����1608����
}
else if( size1 == 24 )
{
temp = asc2_2412[chr1][i]; //����2412����
}
else return;
for( m = 0; m < 8; m++ ) //�����
{
if( temp & 0x80 )OLED_DrawPoint( x, y ,mode);
//else OLED_ClearPoint( x, y);
else OLED_DrawPoint( x, y ,!mode);
temp <<= 1;
y++;
if( ( y - y0 ) == size1 )
{
y = y0;
x++;
break;
}
}
}
}
//��ʾ�ַ���
//x,y:�������
//size1:�����С
//*chr:�ַ�����ʼ��ַ
void OLED_ShowString( u8 x, u8 y, u8* chr, u8 size1,u8 mode )
{
while( ( *chr >= ' ' ) && ( *chr <= '~' ) ) //�ж��Dz��ǷǷ��ַ�!
{
OLED_ShowChar( x, y, *chr, size1,mode );
x += size1 / 2;
if( x > 128 - size1 ) //����
{
x = 0;
y += 2;
}
chr++;
}
}
//m^n
u32 OLED_Pow( u8 m, u8 n )
{
u32 result = 1;
while( n-- )
{
result *= m;
}
return result;
}
////��ʾ2������
////x,y :�������
////len :���ֵ�λ��
////size:�����С
void OLED_ShowNum( u8 x, u8 y, u32 num, u8 len, u8 size1, u8 mode)
{
u8 t, temp;
for( t = 0; t < len; t++ )
{
temp = ( num / OLED_Pow( 10, len - t - 1 ) ) % 10;
if( temp == 0 )
{
OLED_ShowChar( x + ( size1 / 2 )*t, y, '0', size1, mode );
}
else
{
OLED_ShowChar( x + ( size1 / 2 )*t, y, temp + '0', size1,mode );
}
}
}
//��ʾ����
//x,y:�������
//num:���ֶ�Ӧ�����
void OLED_ShowChinese( u8 x, u8 y, u8 num, u8 size1, u8 mode )
{
u8 i, m, n = 0, temp, chr1;
u8 x0 = x, y0 = y;
u8 size3 = size1 / 8;
while( size3-- )
{
chr1 = num * size1 / 8 + n;
n++;
for( i = 0; i < size1; i++ )
{
if( size1 == 16 )
{
temp = Hzk1[chr1][i]; //����16*16����
}
else if( size1 == 24 )
{
temp = Hzk2[chr1][i]; //����24*24����
}
else if( size1 == 32 )
{
temp = Hzk3[chr1][i]; //����32*32����
}
else if( size1 == 64 )
{
temp = Hzk4[chr1][i]; //����64*64����
}
else return;
for( m = 0; m < 8; m++ )
{
if( temp & 0x01 )OLED_DrawPoint( x, y ,mode);
//else OLED_ClearPoint( x, y );
else OLED_DrawPoint( x, y ,!mode);
temp >>= 1;
y++;
}
x++;
if( ( x - x0 ) == size1 )
{
x = x0;
y0 = y0 + 8;
}
y = y0;
}
}
}
//num ��ʾ���ֵĸ���
//space ÿһ����ʾ�ļ��
void OLED_ScrollDisplay( u8 num, u8 space , u8 mode)
{
u8 i, n, t = 0, m = 0, r;
while( 1 )
{
if( m == 0 )
{
OLED_ShowChinese( 128, 24, t, 16, mode); //д��һ�����ֱ�����OLED_GRAM[][]������
t++;
}
if( t == num )
{
for( r = 0; r < 16 * space; r++ ) //��ʾ���
{
for( i = 0; i < 144; i++ )
{
for( n = 0; n < 8; n++ )
{
OLED_GRAM[i - 1][n] = OLED_GRAM[i][n];
}
}
OLED_Refresh();
}
t = 0;
}
m++;
if( m == 16 )
{
m = 0;
}
for( i = 0; i < 144; i++ ) //ʵ������
{
for( n = 0; n < 8; n++ )
{
OLED_GRAM[i - 1][n] = OLED_GRAM[i][n];
}
}
OLED_Refresh();
}
}
//����д�����ݵ���ʼλ��
void OLED_WR_BP( u8 x, u8 y )
{
OLED_WR_Byte( 0xb0 + y, OLED_CMD ); //��������ʼ��ַ
OLED_WR_Byte( ( ( x & 0xf0 ) >> 4 ) | 0x10, OLED_CMD );
OLED_WR_Byte( ( x & 0x0f ) | 0x01, OLED_CMD );
}
//x0,y0���������
//x1,y1���յ�����
//BMP[]��Ҫд���ͼƬ����
void OLED_ShowPicture( u8 x0, u8 y0, u8 x1, u8 y1, u8 BMP[] )
{
u32 j = 0;
u8 x = 0, y = 0;
if( y % 8 == 0 )y = 0;
else y += 1;
for( y = y0; y < y1; y++ )
{
OLED_WR_BP( x0, y );
for( x = x0; x < x1; x++ )
{
OLED_WR_Byte( BMP[j], OLED_DATA );
j++;
}
}
}
//OLED�ij�ʼ��
void OLED_Init( void )
{
rcu_periph_clock_enable(RCU_GPIOB);
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,GPIO_PIN_4|GPIO_PIN_3);
gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_MAX,GPIO_PIN_4|GPIO_PIN_3);
OLED_SDIN_Set();
OLED_SCLK_Set();
// OLED_RST_Set();
// delay_ms(100);
// OLED_RST_Clr();//��λ
// delay_ms(200);
// OLED_RST_Set();
// OLED_DC_Clr();
delay_1ms(2000);
OLED_WR_Byte( 0xAE, OLED_CMD ); //--turn off oled panel
OLED_WR_Byte( 0x00, OLED_CMD ); //---set low column address
OLED_WR_Byte( 0x10, OLED_CMD ); //---set high column address
OLED_WR_Byte( 0x40, OLED_CMD ); //--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
OLED_WR_Byte( 0x81, OLED_CMD ); //--set contrast control register
OLED_WR_Byte( 0xCF, OLED_CMD ); // Set SEG Output Current Brightness
OLED_WR_Byte( 0xA1, OLED_CMD ); //--Set SEG/Column Mapping 0xa0���ҷ��� 0xa1����
OLED_WR_Byte( 0xC8, OLED_CMD ); //Set COM/Row Scan Direction 0xc0���·��� 0xc8����
OLED_WR_Byte( 0xA6, OLED_CMD ); //--set normal display
OLED_WR_Byte( 0xA8, OLED_CMD ); //--set multiplex ratio(1 to 64)
OLED_WR_Byte( 0x3f, OLED_CMD ); //--1/64 duty
OLED_WR_Byte( 0xD3, OLED_CMD ); //-set display offset Shift Mapping RAM Counter (0x00~0x3F)
OLED_WR_Byte( 0x00, OLED_CMD ); //-not offset
OLED_WR_Byte( 0xd5, OLED_CMD ); //--set display clock divide ratio/oscillator frequency
OLED_WR_Byte( 0x80, OLED_CMD ); //--set divide ratio, Set Clock as 100 Frames/Sec
OLED_WR_Byte( 0xD9, OLED_CMD ); //--set pre-charge period
OLED_WR_Byte( 0xF1, OLED_CMD ); //Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
OLED_WR_Byte( 0xDA, OLED_CMD ); //--set com pins hardware configuration
OLED_WR_Byte( 0x12, OLED_CMD );
OLED_WR_Byte( 0xDB, OLED_CMD ); //--set vcomh
OLED_WR_Byte( 0x40, OLED_CMD ); //Set VCOM Deselect Level
OLED_WR_Byte( 0x20, OLED_CMD ); //-Set Page Addressing Mode (0x00/0x01/0x02)
OLED_WR_Byte( 0x02, OLED_CMD ); //
OLED_WR_Byte( 0x8D, OLED_CMD ); //--set Charge Pump enable/disable
OLED_WR_Byte( 0x14, OLED_CMD ); //--set(0x10) disable
OLED_WR_Byte( 0xA4, OLED_CMD ); // Disable Entire Display On (0xa4/0xa5)
OLED_WR_Byte( 0xA6, OLED_CMD ); // Disable Inverse Display On (0xa6/a7)
OLED_Clear();
OLED_WR_Byte( 0xAF, OLED_CMD );
}
使用软件模拟一定要注意,不要使用GPIO_BC(gpiox)、GPIO_BOP(gpiox) 还有gpio_bit_write(uint32_t gpio_periph, uint32_t pin, bit_status bit_value);千万不要用,要用就用下面这两个,坑死人啊
void gpio_bit_set(uint32_t gpio_periph, uint32_t pin);
/* reset GPIO pin bit */
void gpio_bit_reset(uint32_t gpio_periph, uint32_t pin);
