软件模拟8080通信

软件模拟8080通信

8080 接口(也叫 I8080)是一种并行、异步、半双工总线,常见于 LCD/TFT 屏驱动(如 ILI9341、ILI9488、NT35510),核心是WR 上升沿写、RD 上升沿读。

一、接口信号(8/16/24 位)

CS:片选,低有效;CS=0 时芯片被选中。

RS / DC:命令 / 数据选择;0 = 命令,1 = 数据

WR:写信号,低有效;上升沿锁存数据。

RD:读信号,低有效;上升沿读取数据。

D[7:0] / D[15:0] / D[23:0]:双向并行数据线。

要注意的是:WR、RD 不能同时为低

二、基本时序

1.写命令:

CS = 0(片选选中)

RS = 0(命令)

RD = 1 (WR、RD 不能同时为低,因为是写,所以禁止读)

D [X:0] = 命令值

WR = 0(开始写)

WR = 1(从机读)

CS = 1(释放)

2.写数据

时序同上,仅需将RS改为=1(写的是数据)

3.读数据

CS = 0(选中)

RS = 1(数据)

WR = 1(禁止写)

RD = 0(开始读)

data = D [X:0](读取各个数据线的电平状态)

RD = 1

CS = 1

三、完整代码

my8080.h

#ifndef __MY_8080_H #define __MY_8080_H #include "stm32f10x.h" // 引脚初始化 void my8080_pinInit(void); // 写命令 void my8080_writeCommand(uint16_t command); // 写数据 void my8080_writeData(uint16_t data); // 读数据 uint16_t my8080_readData(void); #endif

my8080.c

#include "my_8080.h" #define D0_pin GPIO_Pin_14 #define D0_port GPIOD #define D1_pin GPIO_Pin_15 #define D1_port GPIOD #define D2_pin GPIO_Pin_0 #define D2_port GPIOD #define D3_pin GPIO_Pin_1 #define D3_port GPIOD #define D4_pin GPIO_Pin_7 #define D4_port GPIOE #define D5_pin GPIO_Pin_8 #define D5_port GPIOE #define D6_pin GPIO_Pin_9 #define D6_port GPIOE #define D7_pin GPIO_Pin_10 #define D7_port GPIOE #define D8_pin GPIO_Pin_11 #define D8_port GPIOE #define D9_pin GPIO_Pin_12 #define D9_port GPIOE #define D10_pin GPIO_Pin_13 #define D10_port GPIOE #define D11_pin GPIO_Pin_14 #define D11_port GPIOE #define D12_pin GPIO_Pin_15 #define D12_port GPIOE #define D13_pin GPIO_Pin_8 #define D13_port GPIOD #define D14_pin GPIO_Pin_9 #define D14_port GPIOD #define D15_pin GPIO_Pin_10 #define D15_port GPIOD // 写信号 #define WR_pin GPIO_Pin_5 #define WR_port GPIOD // 读信号 #define RD_pin GPIO_Pin_4 #define RD_port GPIOD // 片选 #define CS_pin GPIO_Pin_12 #define CS_port GPIOG // 数据or命令选择 #define DC_pin GPIO_Pin_0 #define DC_port GPIOG // 片选 #define CS(x) GPIO_WriteBit(CS_port, CS_pin, (x) ? Bit_SET : Bit_RESET) // 数据or命令选择 #define DC(x) GPIO_WriteBit(DC_port, DC_pin, (x) ? Bit_SET : Bit_RESET) // 写信号 #define WR(x) GPIO_WriteBit(WR_port, WR_pin, (x) ? Bit_SET : Bit_RESET) // 读信号 #define RD(x) GPIO_WriteBit(RD_port, RD_pin, (x) ? Bit_SET : Bit_RESET) // 设置数据引脚为输出模式 static void setDataPinMode_Output(void) { GPIO_InitTypeDef GPIO_InitStructure = {0}; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin = D0_pin | D1_pin | D2_pin | D3_pin | D13_pin|D14_pin|D15_pin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOD, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = D4_pin | D5_pin | D6_pin | D7_pin | D8_pin|D9_pin|D10_pin|D11_pin|D12_pin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOE, &GPIO_InitStructure); } // 设置数据引脚为输入模式 static void setDataPinMode_Input(void) { GPIO_InitTypeDef GPIO_InitStructure = {0}; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin = D0_pin | D1_pin | D2_pin | D3_pin | D13_pin|D14_pin|D15_pin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOD, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = D4_pin | D5_pin | D6_pin | D7_pin | D8_pin|D9_pin|D10_pin|D11_pin|D12_pin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOE, &GPIO_InitStructure); } // 引脚初始化 void my8080_pinInit(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE); GPIO_InitTypeDef GPIO_InitStructure = {0}; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // WR GPIO_InitStructure.GPIO_Pin = WR_pin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(WR_port, &GPIO_InitStructure); // RD GPIO_InitStructure.GPIO_Pin = RD_pin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(RD_port, &GPIO_InitStructure); // CS GPIO_InitStructure.GPIO_Pin = CS_pin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(CS_port, &GPIO_InitStructure); // DC GPIO_InitStructure.GPIO_Pin = DC_pin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(DC_port, &GPIO_InitStructure); // CS、WR、RD 初始化为高电平 WR(1); RD(1); CS(1); // 设置数据引脚为输入模式 setDataPinMode_Input(); } // 往数据总线写入数据 static void putData(uint16_t data) { setDataPinMode_Output(); // 设置数据引脚为输出模式 GPIO_WriteBit(D0_port, D0_pin, (data & 0x0001 << 0) ? Bit_SET : Bit_RESET); GPIO_WriteBit(D1_port, D1_pin, (data & 0x0001 << 1) ? Bit_SET : Bit_RESET); GPIO_WriteBit(D2_port, D2_pin, (data & 0x0001 << 2) ? Bit_SET : Bit_RESET); GPIO_WriteBit(D3_port, D3_pin, (data & 0x0001 << 3) ? Bit_SET : Bit_RESET); GPIO_WriteBit(D4_port, D4_pin, (data & 0x0001 << 4) ? Bit_SET : Bit_RESET); GPIO_WriteBit(D5_port, D5_pin, (data & 0x0001 << 5) ? Bit_SET : Bit_RESET); GPIO_WriteBit(D6_port, D6_pin, (data & 0x0001 << 6) ? Bit_SET : Bit_RESET); GPIO_WriteBit(D7_port, D7_pin, (data & 0x0001 << 7) ? Bit_SET : Bit_RESET); GPIO_WriteBit(D8_port, D8_pin, (data & 0x0001 << 8) ? Bit_SET : Bit_RESET); GPIO_WriteBit(D9_port, D9_pin, (data & 0x0001 << 9) ? Bit_SET : Bit_RESET); GPIO_WriteBit(D10_port, D10_pin, (data & 0x0001 << 10) ? Bit_SET : Bit_RESET); GPIO_WriteBit(D11_port, D11_pin, (data & 0x0001 << 11) ? Bit_SET : Bit_RESET); GPIO_WriteBit(D12_port, D12_pin, (data & 0x0001 << 12) ? Bit_SET : Bit_RESET); GPIO_WriteBit(D13_port, D13_pin, (data & 0x0001 << 13) ? Bit_SET : Bit_RESET); GPIO_WriteBit(D14_port, D14_pin, (data & 0x0001 << 14) ? Bit_SET : Bit_RESET); GPIO_WriteBit(D15_port, D15_pin, (data & 0x0001 << 15) ? Bit_SET : Bit_RESET); } // 从数据总线读取数据 static uint16_t getData(void) { setDataPinMode_Input(); // 设置数据引脚为输入模式 uint16_t data = 0; data |= GPIO_ReadInputDataBit(D0_port, D0_pin) << 0; data |= GPIO_ReadInputDataBit(D1_port, D1_pin) << 1; data |= GPIO_ReadInputDataBit(D2_port, D2_pin) << 2; data |= GPIO_ReadInputDataBit(D3_port, D3_pin) << 3; data |= GPIO_ReadInputDataBit(D4_port, D4_pin) << 4; data |= GPIO_ReadInputDataBit(D5_port, D5_pin) << 5; data |= GPIO_ReadInputDataBit(D6_port, D6_pin) << 6; data |= GPIO_ReadInputDataBit(D7_port, D7_pin) << 7; data |= GPIO_ReadInputDataBit(D8_port, D8_pin) << 8; data |= GPIO_ReadInputDataBit(D9_port, D9_pin) << 9; data |= GPIO_ReadInputDataBit(D10_port, D10_pin) << 10; data |= GPIO_ReadInputDataBit(D11_port, D11_pin) << 11; data |= GPIO_ReadInputDataBit(D12_port, D12_pin) << 12; data |= GPIO_ReadInputDataBit(D13_port, D13_pin) << 13; data |= GPIO_ReadInputDataBit(D14_port, D14_pin) << 14; data |= GPIO_ReadInputDataBit(D15_port, D15_pin) << 15; return data; } // 写命令 void my8080_writeCommand(uint16_t command) { CS(0); // 拉低片选 DC(0); // 拉低表示写命令 RD(1); // 确保释放读信号 (读和写不能同时拉低) putData(command); // 写入命令数据 WR(0); // 拉低写信号 开始写 WR(1); // 拉高写信号 从机读 CS(1); // 拉高片选 } // 写数据 void my8080_writeData(uint16_t data) { CS(0); // 拉低片选 DC(1); // 拉高表示写数据 RD(1); // 确保释放读信号 (读和写不能同时拉低) putData(data); // 写入数据 WR(0); // 拉低写信号 开始写 WR(1); // 拉高写信号 从机读 CS(1); // 拉高片选 } // 读数据 uint16_t my8080_readData(void) { uint16_t data; CS(0); // 拉低片选 DC(1); // 拉高表示读数据 WR(1); // 确保释放写信号 (读和写不能同时拉低) RD(0); // 拉低读信号 从机放数据 data = getData(); // 主机读 RD(1); // 拉高读信号 从机释放数据总线 CS(1); // 拉高片选 return data; }