单机机为STC8H8K64U,外置40MHZ晶振,源代码如下。
-
- #include "STC8H.H"
- #include <intrins.h>
- #define I2C_SEL 0x10
- #define OLED_PAGE_NUM 6
- #define OLED_COL_NUM 64
- #define OLED_COL_OFFSET 32
- code unsigned char font[36][8] = {
- {0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x3C},
- {0x10,0x38,0x10,0x10,0x10,0x10,0x10,0x38},
- {0x3C,0x42,0x42,0x04,0x08,0x10,0x20,0x7E},
- {0x3C,0x42,0x02,0x0C,0x02,0x42,0x42,0x3C},
- {0x04,0x0C,0x14,0x24,0x44,0x7E,0x04,0x04},
- {0x7E,0x40,0x40,0x78,0x04,0x02,0x42,0x3C},
- {0x3C,0x42,0x40,0x7C,0x42,0x42,0x42,0x3C},
- {0x7E,0x02,0x04,0x08,0x10,0x20,0x40,0x40},
- {0x3C,0x42,0x42,0x3C,0x42,0x42,0x42,0x3C},
- {0x3C,0x42,0x42,0x3E,0x02,0x02,0x42,0x3C},
- {0x00,0x3C,0x42,0x42,0x7E,0x42,0x42,0x00},
- {0x00,0x7C,0x42,0x42,0x7C,0x42,0x42,0x7C},
- {0x00,0x3C,0x42,0x40,0x40,0x42,0x3C,0x00},
- {0x00,0x7C,0x42,0x42,0x42,0x42,0x42,0x7C},
- {0x00,0x7E,0x40,0x40,0x7C,0x40,0x40,0x7E},
- {0x00,0x7E,0x40,0x40,0x7C,0x40,0x40,0x40},
- {0x00,0x3C,0x42,0x40,0x4E,0x42,0x42,0x3C},
- {0x00,0x42,0x42,0x42,0x7E,0x42,0x42,0x42},
- {0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x38},
- {0x00,0x06,0x02,0x02,0x02,0x02,0x42,0x3C},
- {0x00,0x42,0x44,0x48,0x70,0x48,0x44,0x42},
- {0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x7E},
- {0x00,0x42,0x66,0x5A,0x5A,0x42,0x42,0x42},
- {0x00,0x42,0x62,0x52,0x4A,0x46,0x42,0x42},
- {0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x3C},
- {0x00,0x7C,0x42,0x42,0x7C,0x40,0x40,0x40},
- {0x00,0x3C,0x42,0x42,0x42,0x4A,0x3C,0x02},
- {0x00,0x7C,0x42,0x42,0x7C,0x48,0x44,0x42},
- {0x00,0x3C,0x42,0x20,0x18,0x04,0x42,0x3C},
- {0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0x10},
- {0x00,0x42,0x42,0x42,0x42,0x42,0x42,0x3C},
- {0x00,0x42,0x42,0x42,0x42,0x24,0x18,0x00},
- {0x00,0x42,0x42,0x42,0x5A,0x5A,0x66,0x42},
- {0x00,0x42,0x24,0x18,0x18,0x24,0x42,0x00},
- {0x00,0x42,0x42,0x24,0x18,0x10,0x20,0x40},
- {0x00,0x7E,0x04,0x08,0x10,0x20,0x40,0x7E}
- };
- void delay_ms(unsigned int t)
- {
- unsigned char i, j;
- while (t--) { i = 50; j = 100; while (--j) while (--i); }
- }
-
- /* ── 时钟初始化:外部晶振 40MHz ── */
- void Clock_Init(void)
- {
- P_SW2 |= 0x80; // 使能访问XFR
- XOSCCR = 0xC0; // 使能外部晶振
- while (!(XOSCCR & 0x01)); // 等待外部晶振稳定
- CLKDIV = 0x00; // 不分频
- CLKSEL = 0x01; // 选择外部晶振作为时钟源
- }
-
- /* ── 硬件I2C初始化 ── */
- void I2C_Init(void)
- {
- P_SW2 |= 0x80; // 使能访问XFR
- P_SW2 = (P_SW2 & ~0x30) | I2C_SEL; // I2C脚选P2.5/P2.4
- /* MSSPEED=23:I2C总线速度 = 40M/2/(23*2+4) ≈ 400kHz */
- I2CCFG = 0x80 | 0x40 | 23; // ENI2C=1, MSSL=1(主机), 速度控制
- P2M1 &= ~0x30; // P2.4/P2.5 准双向/开漏
- P2M0 |= 0x30;
- }
-
- void I2C_Wait(void)
- {
- while (!(I2CMSST & 0x40)); // 等待MSIF中断标志置位
- I2CMSST &= ~0x40; // 清除中断标志
- }
-
- void I2C_Start(unsigned char addr)
- {
- I2CTXD = (addr << 1); // 设备地址 + 写位
- I2CMSCR = 0x09; // 起始+发送数据+接收ACK
- I2C_Wait();
- }
-
- void I2C_SendByte(unsigned char dat)
- {
- I2CTXD = dat;
- I2CMSCR = 0x0A; // 发送数据+接收ACK
- I2C_Wait();
- }
-
- void I2C_Stop(void)
- {
- I2CMSCR = 0x06; // 停止
- I2C_Wait();
- }
-
- void OLED_WriteCmd(unsigned char cmd)
- {
- I2C_Start(0x3C);
- I2C_SendByte(0x00); // 控制字节=命令
- I2C_SendByte(cmd);
- I2C_Stop();
- }
-
- void OLED_WriteData(unsigned char dat)
- {
- I2C_Start(0x3C);
- I2C_SendByte(0x40); // 控制字节=数据
- I2C_SendByte(dat);
- I2C_Stop();
- }
-
- /* 设置列地址:column为屏幕列号(0~63),内部自动加32偏移 */
- void OLED_SetColumn(unsigned char column)
- {
- column += OLED_COL_OFFSET; // 64×48屏显示区从内部第32列开始
- OLED_WriteCmd(0x10 | ((column >> 4) & 0x0F));
- OLED_WriteCmd(0x00 | (column & 0x0F));
- }
-
- void OLED_SetPage(unsigned char page)
- {
- OLED_WriteCmd(0xB0 + page); // 页0~5
- }
-
- /* 清屏:6页 × 64列 */
- void OLED_Clear(void)
- {
- unsigned char page, column;
- for (page = 0; page < OLED_PAGE_NUM; page++) // 6页
- {
- OLED_SetPage(page);
- OLED_SetColumn(0); // 起始列(屏幕0,内部32)
- I2C_Start(0x3C);
- I2C_SendByte(0x40); // 数据模式
- for (column = 0; column < OLED_COL_NUM; column++)
- I2C_SendByte(0x00);
- I2C_Stop();
- }
- }
-
- /* 显示单个字符(按列组织字形),列号0~63 */
- void OLED_ShowChar(unsigned char page, unsigned char column, char ch)
- {
- unsigned char i, j, index = 0xFF;
- unsigned char col_data;
- if (ch >= '0' && ch <= '9') index = ch - '0';
- else if (ch >= 'a' && ch <= 'z') index = 10 + (ch - 'a');
- else return;
-
- OLED_SetPage(page);
- OLED_SetColumn(column);
- I2C_Start(0x3C);
- I2C_SendByte(0x40);
- for (j = 0; j < 8; j++) // 8列
- {
- col_data = 0;
- for (i = 0; i < 8; i++) // 每列8像素
- {
- if (font[index][i] & (0x80 >> j))
- col_data |= (0x01 << i);
- }
- I2C_SendByte(col_data);
- }
- I2C_Stop();
- }
-
- /* 显示字符串:64列/8=8字符,列号上限56 */
- void OLED_ShowString(unsigned char page, unsigned char column, char *str)
- {
- while (*str != '\0')
- {
- if (column > (OLED_COL_NUM - 8)) break; // 56
- OLED_ShowChar(page, column, *str);
- column += 8;
- str++;
- }
- }
-
- /* OLED初始化(0.66寸 64×48, SSD1315 参数) */
- void OLED_Init(void)
- {
- OLED_WriteCmd(0xAE); // 关闭显示
- OLED_WriteCmd(0x00); // 列地址高
- OLED_WriteCmd(0x10); // 列地址低
- OLED_WriteCmd(0x40); // 起始行0
- OLED_WriteCmd(0x20); // 页地址模式
- OLED_WriteCmd(0x02);
- OLED_WriteCmd(0xB0); // 页地址
- OLED_WriteCmd(0x81); // 对比度
- OLED_WriteCmd(0xFF);
- OLED_WriteCmd(0xA1); // 段重映射
- OLED_WriteCmd(0xC8); // COM扫描方向
- OLED_WriteCmd(0xA4); // RAM内容显示
- OLED_WriteCmd(0xA6); // 正常显示
- OLED_WriteCmd(0xA8); // 多路复用比
- OLED_WriteCmd(0x30); // ★ 48行 (64×48屏)
- OLED_WriteCmd(0xD3); // 显示偏移
- OLED_WriteCmd(0x3F);
- OLED_WriteCmd(0xD5); // 时钟分频
- OLED_WriteCmd(0x80);
- OLED_WriteCmd(0xD9); // 预充电
- OLED_WriteCmd(0xF1);
- OLED_WriteCmd(0xDA); // ★ COM引脚配置
- OLED_WriteCmd(0x12); // ★ 64×48屏专用(不能再用0x02)
- OLED_WriteCmd(0xDB); // VCOMH
- OLED_WriteCmd(0x40);
- OLED_WriteCmd(0x8D); // 电荷泵
- OLED_WriteCmd(0x14);
- OLED_Clear();
- OLED_WriteCmd(0xAF); // 打开显示
- }
- void main(void)
- {
- Clock_Init();
- I2C_Init();
- OLED_Init();
-
- /* 显示6行,每行8个字符(8字符 x 6行 = 48字符,覆盖 font 前48个字形) */
- OLED_ShowString(0, 0, "01234567"); // page 0 ← 第1行
- OLED_ShowString(1, 0, "89abcdef"); // page 1 ← 第2行
- OLED_ShowString(2, 0, "ghijklmn"); // page 2 ← 第3行
- OLED_ShowString(3, 0, "opqrstuv"); // page 3 ← 第4行
- OLED_ShowString(4, 0, "wxyz0123"); // page 4 ← 第5行
- OLED_ShowString(5, 0, "456789ab"); // page 5 ← 第6行(最后一行)
-
- while (1)
- {
- delay_ms(1000);
- }
- }
复制代码
6448-iic.c
(7.69 KB, 下载次数: 72)
|