背景

指导学弟毕设,因为开发板型号不同(一个是ZET6,一个是C8T6),所以例程上面的DATA口所插的PG11口在他的板子上面找不到,改了半天程序,一直显示检测不到DHT11,很是恼火。
经过差不多两个小时的查看与寻找资料,终于发现问题了,问题其实不难发现,但是初学者如果没有遇到过,就很容易忽视。

正常的修改

正常情况下,如果要修改引脚,到相应的.c或.h扫一眼就行了,比如这次要把PG11改成PA1,但凡发现GPIOG全都改成GPIOA,发现pin_11,全部改成pin_1,基本上都能OK,我也是这样,首先修改.c:

u8 DHT11_Init(void)
{	 
 	GPIO_InitTypeDef  GPIO_InitStructure;
 	
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE);	 //使能PG端口时钟
	
 	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;				 //11改成1
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOG, &GPIO_InitStructure);				 //G改成A
 	GPIO_SetBits(GPIOG,GPIO_Pin_11);						 //G改成A,11改成1			    
	DHT11_Rst();  //复位DHT11
	return DHT11_Check();//等待DHT11的回应
}

再修改.h:

#define	DHT11_DQ_OUT PGout(11) //G改成A,11改成1
#define	DHT11_DQ_IN  PGin(11)  //G改成A,11改成1

然后编译、下载,全程都没有错误,但是下载以后总是无法运行,在初始化DHT11的时候就不行。

容易忽视的点

想了很久,又看了别人的文件,发现.h里面还有两行:

#define DHT11_IO_IN()  {GPIOG->CRH&=0XFFFF0FFF;GPIOG->CRH|=8<<12;}
#define DHT11_IO_OUT() {GPIOG->CRH&=0XFFFF0FFF;GPIOG->CRH|=3<<12;}

也是跟G有关的,将里面所有的G全部改成A以后,还是不行。。。
上网找关于CRH的资料:

STM32的CRL控制着个IO端口(A~G)的低8位(即0~7,同理 高八位是8~15)的模式。每个IO端口的位占用CRL的4个位,高两位为CNF,低两位为MODE。这里我们可以记住几个常用的配置,比如0X4表示模拟输入模式(ADC用)、0X3表示推挽输出模式(做输出口用,50M速率)、0X8表示上/下拉输入模式(做输入口用)、0XB表示复用输出(使用IO口的第二功能,50M速率)。
CRH的作用和CRL完全一样,只是CRL控制的是低8位输出口,而CRH控制的是高8位输出口。

恍然大悟,上面第一行的代码意思是先将相应位置清零,再打上8,也就是输入,最后的12是3个4位,高位从8开始,<<12指向的就是PG8口,第二行的意思是:先将相应位置清零,再打上3,也就是推挽输出
所以,上述代码修改为:

#define DHT11_IO_IN()  {GPIOA->CRL&=0XFFFFFF0F;GPIOA->CRL|=8<<4;}
#define DHT11_IO_OUT() {GPIOA->CRL&=0XFFFFFF0F;GPIOA->CRL|=3<<4;}

改动的地方有:G口改为A口,CRH改为CRL(因为之前的11属于高位,这里的1属于地位),0XFFFF0FFF改为0XFFFFFF0F,最后的12改成4.

测试一下,成功。