完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一、GPIO基础
问题:GPIO指的是什么?是不是引脚越多越好? General Purpose Input Output通用的输入输出接口;其实引脚够用就好,选择适用数目合理的芯片便可。 STM8单片机GPIO所支持的模式: 1、输入模式及特点
LQFP 薄型四方扁平式封装
三、配置寄存器的位运算操作 (按位或|,按位与&,按位取反~,左移>>,右移<<) 需要注意,||是逻辑或,&&是逻辑与,其结果只有01,不是位操作。 位或运算,也就是置1操作,将某一个位变成1 eg: PB_DDR |= 0x44; PB_DDR |= (0x1<<3); 位与运算,也就是清0操作,将某一个位变成0 eg: PB_DDR &= 0x44; PB_DDR &= ~(0x1<<3); 取值运算,读取端口状态并赋值给变量“x” eg: x = (PB_IDR >> 2) & 0x01; //读取PB2端口状态 配置PB组端口高4位为2MHz斜率开漏输出模式,低四位为10MHz斜率推晚输出模式,让端口输出“01010111”电平状态 PB_DDR = 0xFF; PB_CR1 = 0x0F; PB_CR2 = 0x0F; PB_ODR = 0x57 其中,由于IAR为我们编写了一个五千多行的头文件,可以支持直接操作相关位,比较的方便,而STVD是不支持的,也就是两个软件代码进行移植的时候需要进行更改。IAR头文件多带来的遍历: /*--------------------------------------------------------- * Port B bit fields *-------------------------------------------------------*/ #ifdef __IAR_SYSTEMS_ICC__ #define PB_ODR_ODR0 PB_ODR_bit.ODR0 #define PB_ODR_ODR1 PB_ODR_bit.ODR1 #define PB_ODR_ODR2 PB_ODR_bit.ODR2 #define PB_ODR_ODR3 PB_ODR_bit.ODR3 #define PB_ODR_ODR4 PB_ODR_bit.ODR4 #define PB_ODR_ODR5 PB_ODR_bit.ODR5 #define PB_ODR_ODR6 PB_ODR_bit.ODR6 #define PB_ODR_ODR7 PB_ODR_bit.ODR7 #define PB_IDR_IDR0 PB_IDR_bit.IDR0 #define PB_IDR_IDR1 PB_IDR_bit.IDR1 #define PB_IDR_IDR2 PB_IDR_bit.IDR2 #define PB_IDR_IDR3 PB_IDR_bit.IDR3 #define PB_IDR_IDR4 PB_IDR_bit.IDR4 #define PB_IDR_IDR5 PB_IDR_bit.IDR5 #define PB_IDR_IDR6 PB_IDR_bit.IDR6 #define PB_IDR_IDR7 PB_IDR_bit.IDR7 #define PB_DDR_DDR0 PB_DDR_bit.DDR0 #define PB_DDR_DDR1 PB_DDR_bit.DDR1 #define PB_DDR_DDR2 PB_DDR_bit.DDR2 #define PB_DDR_DDR3 PB_DDR_bit.DDR3 #define PB_DDR_DDR4 PB_DDR_bit.DDR4 #define PB_DDR_DDR5 PB_DDR_bit.DDR5 #define PB_DDR_DDR6 PB_DDR_bit.DDR6 #define PB_DDR_DDR7 PB_DDR_bit.DDR7 #define PB_CR1_C10 PB_CR1_bit.C10 #define PB_CR1_C11 PB_CR1_bit.C11 #define PB_CR1_C12 PB_CR1_bit.C12 #define PB_CR1_C13 PB_CR1_bit.C13 #define PB_CR1_C14 PB_CR1_bit.C14 #define PB_CR1_C15 PB_CR1_bit.C15 #define PB_CR1_C16 PB_CR1_bit.C16 #define PB_CR1_C17 PB_CR1_bit.C17 #define PB_CR2_C20 PB_CR2_bit.C20 #define PB_CR2_C21 PB_CR2_bit.C21 #define PB_CR2_C22 PB_CR2_bit.C22 #define PB_CR2_C23 PB_CR2_bit.C23 #define PB_CR2_C24 PB_CR2_bit.C24 #define PB_CR2_C25 PB_CR2_bit.C25 #define PB_CR2_C26 PB_CR2_bit.C26 #define PB_CR2_C27 PB_CR2_bit.C27 #endif 四、流水灯与按键 1、左移流水灯 void LED_Left_Play2(void) { u8 x = 0xFE; u8 i = 0; for(i = 0; i <4; i++){ PI_ODR = x; delay_ms(20); x = x << 1; x |= 0x01; } } 2、右移流水灯 void LED_Right_Play2(void) { u8 x = 0xF7; u8 i = 0; for(i = 0; i < 4; i++){ PI_ODR = x; delay_ms(20); x = x >> 1; x |= 0x80; } } 3、来回循环 void LED_Left_Play(void) //左移流水灯 { PI_ODR_ODR0 = 0; PI_ODR_ODR3 = 1; delay_ms(20); PI_ODR_ODR1 = 0; PI_ODR_ODR0 = 1; delay_ms(20); PI_ODR_ODR2 = 0; PI_ODR_ODR1 = 1; delay_ms(20); PI_ODR_ODR3 = 0; PI_ODR_ODR2 = 1; } void LED_Right_Play(void) //右移流水灯 { PI_ODR_ODR3 = 0; PI_ODR_ODR0 = 1; delay_ms(20); PI_ODR_ODR2 = 0; PI_ODR_ODR3 = 1; delay_ms(20); PI_ODR_ODR1 = 0; PI_ODR_ODR2 = 1; delay_ms(20); PI_ODR_ODR0 = 0; PI_ODR_ODR1 = 1; } 4、流水灯数组设计 void LED_MyDesign(void) { u8 MyLed[8] = {0xFE,0xF7,0xFE,0xF7,0xFD,0xFB,0xFD,0xFB}; u8 MyLed2[8] = {0xF6,0xF9,0xF6,0xF9,0xFA,0xF5,0xFA,0xF5}; u8 MyLed3[9]={0xF6,0xF9,0xF6,0xF9,0xFF,0xF0,0xFF,0xF0,0xFF}; u8 i; for(i = 0; i < 9; i++){ PI_ODR = MyLed3; delay_ms(20); } for(i = 0; i < 8; i++){ PI_ODR = MyLed; delay_ms(20); } for(i = 0; i < 8; i++){ PI_ODR = MyLed2; delay_ms(20); } } 5、按键控制Led灯 #define KEY8 PA_IDR_IDR1 //输入量 #define LED0 PI_ODR_ODR0 //输出量 void Key_For_Led(void) //PA1控制K8 { //键盘按键控制LED灯,PA1控制LED0 PI_DDR_DDR0 = 1; PI_CR1_C10 = 1; PI_CR2_C20 = 0; LED0 = 1; //熄灭 PA_DDR_DDR1 = 0; PA_CR1_C11 = 1; PA_CR2_C21 = 0; while(1){ if(KEY == 0){ //按键按下 delay_ms(5); //消抖 if(KEY == 0){//再次确认按键按下 LED = !LED; //控制LED灯 } while(!KEY); //如果一直处于按下则等待,很关键,需等待到按键松开再启动新一轮的循环 } // while(!KEY); //错误的地方,应该为按键按下的时间段中,所以应该包含在if语句中 } } void delay_ms(u32 time) { u32 i,j; while(time--){ for(i = 0; i < 10; i++){ for(j = 0; j < 100; j++); } } } 6、调试总代码 #include "iostm8s208mb.h" #define u8 uint8_t #define u16 uint16_t #define u32 uint32_t typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned long uint32_t; #define KEY8 PB_IDR_IDR1 //输入量 #define LED0 PI_ODR_ODR0 //输出量 void Key_For_Led(void); void GPIO_Init(void); void LED_light(void); void LED_Right_Play(void); void LED_Left_Play(void); void LED_Right_Play2(void); void LED_Left_Play2(void); void LED_MyDesign(void); void delay_ms(u16 time); u32 count ; int main() { //GPIO_Init(); /* 闪烁灯 PI_ODR_ODR2 = 0; PI_ODR_ODR1 = 0; while(count--){ LED_light(); } */ /* 花样流水灯 while(1) LED_MyDesign(); count = 3; while(count--) LED_Right_Play2(); count = 3; while(count--) LED_Left_Play2(); count = 3; while(count--){ //来回移动 LED_Left_Play(); LED_Right_Play(); } */ Key_For_Led(); } void GPIO_Init(void) //GPIO初始化 { /* PI_DDR_DDR2 = 1; PI_CR1_C12 = 1; PI_CR2_C22 = 0; PI_DDR_DDR1 = 1; PI_CR1_C11 = 1; PI_CR2_C21 = 0; PI_DDR |= 0x09; PI_CR1 |= 0x09; PI_CR2 &= 0xF6; */ PI_DDR |= 0x0F; PI_CR1 |= 0x0F; PI_CR2 &= 0xF0; PI_ODR |= 0x0F; } void Key_For_Led(void) //PA1控制K8 { //键盘按键控制LED灯,PA1控制LED0 PI_DDR_DDR0 = 1; PI_CR1_C10 = 1; PI_CR2_C20 = 0; LED0 = 1; //熄灭 PB_DDR_DDR1 = 0; PB_CR1_C11 = 1; PB_CR2_C21 = 0; while(1){ if(KEY == 0){ //按键按下 delay_ms(5); //消抖 if(KEY == 0){//再次确认按键按下 LED = !LED; //控制LED灯 } while(!KEY); //如果一直处于按下则等待 } } } void LED_MyDesign(void) { u8 MyLed[8] = {0xFE,0xF7,0xFE,0xF7,0xFD,0xFB,0xFD,0xFB}; u8 MyLed2[8] = {0xF6,0xF9,0xF6,0xF9,0xFA,0xF5,0xFA,0xF5}; u8 MyLed3[9]={0xF6,0xF9,0xF6,0xF9,0xFF,0xF0,0xFF,0xF0,0xFF}; u8 i; for(i = 0; i < 9; i++){ PI_ODR = MyLed3; delay_ms(20); } for(i = 0; i < 8; i++){ PI_ODR = MyLed; delay_ms(20); } for(i = 0; i < 8; i++){ PI_ODR = MyLed2; delay_ms(20); } } void LED_light(void) //闪烁灯 { PI_ODR &= 0xF6; delay_ms(20); PI_ODR |= 0x09; delay_ms(20); } void LED_Right_Play2(void) { u8 x = 0xF7; u8 i = 0; for(i = 0; i < 4; i++){ PI_ODR = x; delay_ms(20); x = x >> 1; x |= 0x80; } } void LED_Left_Play2(void) { u8 x = 0xFE; u8 i = 0; for(i = 0; i <4; i++){ PI_ODR = x; delay_ms(20); x = x << 1; x |= 0x01; } } void LED_Left_Play(void) //左移流水灯 { PI_ODR_ODR0 = 0; PI_ODR_ODR3 = 1; delay_ms(20); PI_ODR_ODR1 = 0; PI_ODR_ODR0 = 1; delay_ms(20); PI_ODR_ODR2 = 0; PI_ODR_ODR1 = 1; delay_ms(20); PI_ODR_ODR3 = 0; PI_ODR_ODR2 = 1; } void LED_Right_Play(void) //右移流水灯 { PI_ODR_ODR3 = 0; PI_ODR_ODR0 = 1; delay_ms(20); PI_ODR_ODR2 = 0; PI_ODR_ODR3 = 1; delay_ms(20); PI_ODR_ODR1 = 0; PI_ODR_ODR2 = 1; delay_ms(20); PI_ODR_ODR0 = 0; PI_ODR_ODR1 = 1; } void delay_ms(u16 time) { u8 i,j; while(time--){ for(i = 0; i < 50; i++){ for(j = 0; j < 20; j++); } } } |
|
|
|
只有小组成员才能发言,加入小组>>
imx6ull 和 lan8742 工作起来不正常, ping 老是丢包
3424 浏览 0 评论
3391 浏览 9 评论
3080 浏览 16 评论
3566 浏览 1 评论
9221 浏览 16 评论
1332浏览 3评论
687浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
685浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2432浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
2000浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-3-12 01:44 , Processed in 1.124603 second(s), Total 44, Slave 36 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191