1,74HC165芯片信息
74HC165 是一个 8 位串行或并行输入/串行输出移位寄存器,一般用于单片机的IO扩展。74HC165手册
首先查看74HC165时序图

芯片以时钟信号CP为基准读取或者输出数据。
第1个时钟周期,PL为低电平时,开始同步读取8个DI的状态(D0...D7);
第2个时钟周期,PL恢复为高电平,停止数据读取;
第3个时钟周期,CE为低电平,通过Q7输出D7通道状态值;
从第3个时钟周期开始,每一个时钟周期,Q7顺序输出1位从D7到D0的的通道状态值;
第10个时钟周期,输出最后一个通道D0的状态值,同时CE恢复高电平,停止数据输出。
根据时序图,编写74HC165的驱动程序。
2,STM32的GPIO设置
以STM32F103C8T6为例,使用GPIO_PIN_1~GPIO_PIN_4 4个GPIO通道来连接74HC165。GPIO_PIN_1用于时钟信号(CP)输出,GPIO_PIN_2用于CE输出,GPIO_PIN_3用于PL信号输出,GPIO_PIN_4用于数据接收Q7。GPIO的定义如下:
#define PIN_CP_Pin GPIO_PIN_1 #define PIN_CP_GPIO_Port GPIOA #define PIN_CE_Pin GPIO_PIN_2 #define PIN_CE_GPIO_Port GPIOA #define PIN_PL_Pin GPIO_PIN_3 #define PIN_PL_GPIO_Port GPIOA #define PIN_Q7_Pin GPIO_PIN_4 #define PIN_Q7_GPIO_Port GPIOA
对GPIO功能进行定义:
其中,输出模式需定义为PUSH PULL推挽模式。
/*Configure GPIO pins : PAPin PAPin PAPin */ GPIO_InitStruct.Pin = PIN_CP_Pin|PIN_CE_Pin|PIN_PL_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /*Configure GPIO pin : PtPin */ GPIO_InitStruct.Pin = PIN_Q7_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(PIN_Q7_GPIO_Port, &GPIO_InitStruct);
初始化CP\CE\PL状态
HAL_GPIO_WritePin(GPIOA, PIN_CP_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, PIN_CE_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, PIN_PL_Pin, GPIO_PIN_SET);
3,编写74HC165N驱动程序
int i = 0; uint8_t rlt_bin = 0;//通道采样结果 do { //拉高CP电平,产生时钟上升沿 HAL_GPIO_WritePin(GPIOA, PIN_CP_Pin, GPIO_PIN_SET); switch (i) { case 0: //拉低PL电平,开始同步读取8个di通道数据 HAL_GPIO_WritePin(GPIOA, PIN_PL_Pin, GPIO_PIN_RESET); break; case 1: //拉高PL电平,停止读取通道数据 HAL_GPIO_WritePin(GPIOA, PIN_PL_Pin, GPIO_PIN_SET); break; case 2: //拉低ce,开始顺序读取通道数据 HAL_GPIO_WritePin(GPIOA, PIN_CE_Pin, GPIO_PIN_RESET); //读取第8通道数据 if(HAL_GPIO_ReadPin(GPIOA,PIN_Q7_Pin)==GPIO_PIN_SET) rlt_bin |= (1<<7); break; case 3: //读取第7通道数据 if(HAL_GPIO_ReadPin(GPIOA,PIN_Q7_Pin)==GPIO_PIN_SET) rlt_bin |= (1<<6); break; case 4: //读取第6通道数据 if(HAL_GPIO_ReadPin(GPIOA,PIN_Q7_Pin)==GPIO_PIN_SET) rlt_bin |= (1<<5); break; case 5: //读取第5通道数据 if(HAL_GPIO_ReadPin(GPIOA,PIN_Q7_Pin)==GPIO_PIN_SET) rlt_bin |= (1<<4); break; case 6: //读取第4通道数据 if(HAL_GPIO_ReadPin(GPIOA,PIN_Q7_Pin)==GPIO_PIN_SET) rlt_bin |= (1<<3); break; case 7: //读取第3通道数据 if(HAL_GPIO_ReadPin(GPIOA,PIN_Q7_Pin)==GPIO_PIN_SET) rlt_bin |= (1<<2); break; case 8: //读取第2通道数据 if(HAL_GPIO_ReadPin(GPIOA,PIN_Q7_Pin)==GPIO_PIN_SET) rlt_bin |= (1 << 1); break; case 9: //读取第1通道数据 if(HAL_GPIO_ReadPin(GPIOA,PIN_Q7_Pin)==GPIO_PIN_SET) rlt_bin |= (1<<0); //拉高CE,停止读取 HAL_GPIO_WritePin(GPIOA, PIN_CE_Pin, GPIO_PIN_SET); break; default: break; } //拉低CP电平,产生时钟下降沿 HAL_GPIO_WritePin(GPIOA, PIN_CP_Pin, GPIO_PIN_RESET); } while (i++ < 9); printf("rlt:%X\n",rlt_bin);
读取的通道数据保存在8位无符号数rlt_bin中,该数的每一位记录1个通道的状态。
4,编译保存下装测试
此部分内容不再累述。
浙公网安备 33010602011771号