【求助位带操作】 位带操作的地址放入数组,实现while轮训位带操作的地址

shiguojie19892 2020-10-29 09:47:11
在做一个17芯线缆通断检测的程序,利用10个OUT口和10个IN口,依次控制OUT输出高低电平,希望把OUT口位带地址放进数组里面,请教应该怎么实现?对指针和位带操作的指针放入数组的操作不熟悉,请指教。

代码如下:
*****以下头文件:
#define LINE_NUM_SUM 17

#define OUT0 PAout(0)
#define OUT1 PBout(1)
#define OUT2 PBout(2)
#define OUT3 PBout(3)
#define OUT4 PBout(4)
#define OUT5 PAout(5)
#define OUT6 PBout(6)
#define OUT7 PBout(7)
#define OUT8 PBout(8)
#define OUT9 PBout(9)
#define OUT10 PBout(10)
#define OUT11 PBout(11)
#define OUT12 PBout(12)
#define OUT13 PBout(13)
#define OUT14 PBout(14)
#define OUT15 PBout(15)
#define OUT16 PAout(6)
#define OUT17 PAout(7)

**********以下C文件

void checkInit()
{
u8 i = 0;
GPIO_InitTypeDef GPIO_Initure;

__HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOB时钟
__HAL_RCC_GPIOB_CLK_ENABLE(); //开启GPIOE时钟
__HAL_RCC_GPIOC_CLK_ENABLE(); //开启GPIOE时钟

//OUT 初始化
GPIO_Initure.Pin=GPIO_PIN_0|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7; //0 5 6 7
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出
GPIO_Initure.Pull=GPIO_PULLDOWN; //下拉
GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH; //高速
HAL_GPIO_Init(GPIOA,&GPIO_Initure); //GPIOA OUT

GPIO_Initure.Pin=GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4; //1 2 3 4
GPIO_Initure.Pin|=GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9; //6 7 8 9
GPIO_Initure.Pin|=GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13; //10 11 12 13
GPIO_Initure.Pin|=GPIO_PIN_14|GPIO_PIN_15; //14 15
HAL_GPIO_Init(GPIOB,&GPIO_Initure); //GPIOB OUT

//测试OUT能否循环输出
while(i < LINE_NUM_SUM)
{
if(OUTThis[i])
OUTThis[i] = 0;
else
OUTThis[i] = 1;

delay_ms(1000);
}
}
...全文
10285 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
shiguojie19892 2020-11-02
  • 打赏
  • 举报
回复
这个问题解决了,实现如下: check.c
#include "check.h"
#include "exti.h"
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "lcd.h"

//建立线号检测信息
INFO_ERROR info_err[LINE_NUM_SUM];

//建立i/o口指针数组
volatile unsigned long * OUTThis[LINE_NUM_SUM] = {&OUT0,&OUT1,&OUT2,&OUT3,&OUT4,&OUT5,&OUT6,&OUT7,&OUT8,&OUT9,&OUT10,&OUT11,&OUT12,&OUT13,&OUT14,&OUT15,&OUT16};
volatile unsigned long * INThis[LINE_NUM_SUM] =  {&IN0, &IN1, &IN2, &IN3, &IN4, &IN5, &IN6, &IN7, &IN8, &IN9, &IN10, &IN11, &IN12, &IN13, &IN14, &IN15, &IN16};

void checkInit()
{
	u8 i = 0;
    GPIO_InitTypeDef GPIO_Initure;

    __HAL_RCC_GPIOA_CLK_ENABLE();           	//开启GPIOB时钟
	__HAL_RCC_GPIOB_CLK_ENABLE();           	//开启GPIOE时
	__HAL_RCC_GPIOC_CLK_ENABLE();           	//开启GPIOE时钟
	__HAL_RCC_GPIOF_CLK_ENABLE();           	//开启GPIOE时钟
	__HAL_RCC_GPIOG_CLK_ENABLE();           	//开启GPIOE时钟
	
    __HAL_RCC_AFIO_CLK_ENABLE();

     __HAL_AFIO_REMAP_SWJ_NOJTAG();
	
	//OUT 初始化
    GPIO_Initure.Pin=GPIO_PIN_0|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8; 	//0 5 6 7 8
    GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  	//推挽输出
    GPIO_Initure.Pull=GPIO_PULLDOWN;          	//下拉
    GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;    //高速
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);			//GPIOA OUT

    GPIO_Initure.Pin =GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4; 	//1 2 3 4 
    GPIO_Initure.Pin|=GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_9; 	//6 7 8 9
    GPIO_Initure.Pin|=GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13; 	//10 11 12 13
    HAL_GPIO_Init(GPIOB,&GPIO_Initure);			//GPIOB OUT
	
    GPIO_Initure.Pin=GPIO_PIN_14|GPIO_PIN_15; 							//14 15
    HAL_GPIO_Init(GPIOG,&GPIO_Initure);			//
	
	//IN 初始化
    GPIO_Initure.Pin=GPIO_PIN_1|GPIO_PIN_2; 	//1 2  
    GPIO_Initure.Mode=GPIO_MODE_INPUT;  		//输入
    GPIO_Initure.Pull=GPIO_PULLDOWN;          	//下拉
    GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;    //高速
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);			//GPIOA OUT 16 17

    GPIO_Initure.Pin = GPIO_PIN_8|GPIO_PIN_14|GPIO_PIN_15; 	//8 14 15
    HAL_GPIO_Init(GPIOB,&GPIO_Initure);			//GPIOB 
	
    GPIO_Initure.Pin =GPIO_PIN_9;		 		//9
    GPIO_Initure.Pin|=GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12; 	   // 10 11 12	
    GPIO_Initure.Pin|=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3; 		// 0 1 2 3
    GPIO_Initure.Pin|=GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7; 		// 4 5 6 7 
    HAL_GPIO_Init(GPIOC,&GPIO_Initure);			//GPIOC
	
    GPIO_Initure.Pin =GPIO_PIN_13; 							// 13
    HAL_GPIO_Init(GPIOG,&GPIO_Initure);			//GPIOG
	
	while(i < LINE_NUM_SUM)
	{
		*OUTThis[i] = 0;
		i++;
	}
}

void checkMomentShortCircuitErr()
{
	u8 i = 0;
	u8 chInfo[100];
	
	LCD_ShowString(30,160,400,24,24,"                                  ");
	LCD_ShowString(30,160,400,24,24," moment short check ing... ");
	
	//out口全部置1
	while(i < LINE_NUM_SUM)
	{
		*OUTThis[i] = 1;
		i++;
	}
	
	EXTI_Init();//初始化中断
	
	//等待10秒
	i = LINE_CHECK_TIMER;
	while(0 != i)
	{
		sprintf((char*)chInfo,"check time %02ds",i);
		LCD_ShowString(30,160,400,24,24,"                                  ");
		LCD_ShowString(30,160,400,24,24,chInfo);
		delay_ms(1000);
		i--;
	}
	
	//close exti
	EXTI_DISABLE();
	
	LCD_ShowString(30,160,400,24,24,"********REPORT********");
	//out口全部置0
	i = 0;
	checkInit();
	while(i < LINE_NUM_SUM)
	{
		*OUTThis[i] = 0;
		i++;
	}
}

void checkShortCircuitErr()
{
	u8 i = 0;
	u8 j = 0;
	u8 n = 0;
	
	LCD_ShowString(30,160,400,24,24,"                                  ");
	LCD_ShowString(30,160,400,24,24," short check ing... ");
	
	checkInit();
	
	for(i = 0;i < LINE_NUM_SUM;i++)
	{
		info_err[i].line_num = i;				//写入当前线号
		*OUTThis[i] = 1;						//设置线路高电平
		
		delay_us(1);
		
		//判断是否导通,判断多次
		for(n = 0; n < LINE_CHECK_TIMER; n++)
		{		
			if(1 == *INThis[i])						//检测线路导通
			{
				info_err[i].open_err |= 0;			//导通,不报错
			}
			else
			{
				info_err[i].open_err |= 1;			//不通,报错
				break;								//只要不通,跳出
			}
			delay_ms(1);
		}
		
		//判断与其他线路是否短路
		j = i+1;
		while(j < LINE_NUM_SUM)
		{
			if(1 == *INThis[j])
			{
				info_err[i].short_err |= 1;
				break;
			}
			j++;
		}
		
		info_err[i].short_err |= 0;
		*OUTThis[i] = 0;						//设置线路低电平		
	}
	LCD_ShowString(30,160,400,24,24,"                                      ");
	LCD_ShowString(30,160,400,24,24," short check over. ");
	delay_ms(500);
}
check.h
#ifndef __CHECK_H
#define __CHECK_H

#include "sys.h"

#define LINE_NUM_SUM 		17
#define LINE_CHECK_TIMER 	5

#define OUT0 	PAout(0)
#define OUT1 	PBout(1)
#define OUT2 	PBout(2)
#define OUT3 	PBout(3)
#define OUT4 	PBout(4)
#define OUT5 	PAout(5)
#define OUT6 	PBout(6)
#define OUT7 	PBout(7)
#define OUT8 	PAout(8)
#define OUT9 	PBout(9)
#define OUT10 	PBout(10)
#define OUT11 	PBout(11)
#define OUT12 	PBout(12)
#define OUT13 	PBout(13)
#define OUT14 	PGout(14)
#define OUT15 	PGout(15)
#define OUT16 	PAout(6)
#define OUT17 	PAout(7)

#define IN0		PCin(0)
#define IN1		PCin(1)
#define IN2		PCin(2)
#define IN3		PCin(3)
#define IN4		PCin(4)
#define IN5		PCin(5)
#define IN6		PCin(6)
#define IN7		PCin(7)
#define IN8		PBin(8)
#define IN9		PCin(9)
#define IN10	PCin(10)
#define IN11	PCin(11)
#define IN12	PCin(12)
#define IN13	PGin(13)
#define IN14	PBin(14)
#define IN15	PBin(15)
#define IN16	PAin(1)
#define IN17	PAin(2)

typedef struct
{
	u8 line_num;	//ϟºō
	u8 open_err;	//¶ς·
	u8 short_err;	//¶̂·
	u8 moment_err;	//˲¶ύ
}INFO_ERROR;

void checkInit(void);
void checkShortCircuitErr(void);
void checkMomentShortCircuitErr(void);

#endif 
利用数组指针和位带操作可以轮训GPIO口。
dceacho 2020-10-31
  • 打赏
  • 举报
回复
数组不支持bit类型,你想其他办法吧, 可以用整个端口移位
        while(j < LINE_NUM_SUM)
{
if(1 == (PA>>j))
{
info_err[i].short_err |= 1;
x = PBin(15);
break;
}
j++;
}

shiguojie19892 2020-10-30
  • 打赏
  • 举报
回复
ODR并不是相邻的,怎么轮训,需要把每个地址编入一个地方组队吧? 我现在就是把设置好的GPIO编入数组,然后就可以轮训了,已经实现了OUT,但是IN发现不对呀,IN的取数地址这样不对。
for(i = 0;i < LINE_NUM_SUM;i++)
	{
		info_err[i].line_num = i;				//写入当前线号
		*OUTThis[i] = 1;						//设置线路高电平*****!!!!!注意这里,这个OUT口可以这样操作
		
		delay_us(1);
		
		//判断是否导通
		if(1 == *INThis[i])						//检测线路导通
		{
			info_err[i].open_err |= 0;			//导通,不报错
		}
		else
		{
			info_err[i].open_err |= 1;			//不通,报错
		}
		
		//判断与其他线路是否短路
		j = i+1;
		while(j < LINE_NUM_SUM)
		{
			if(1 == *INThis[j])//这里判断输入,好像不对!!!!!!!!!!!!!!!!!!!!!
			{
				info_err[i].short_err |= 1;
				x = PBin(15);
				break;
			}
			j++;
		}
		
		info_err[i].short_err |= 0;
		*OUTThis[i] = 0;						//设置线路低电平		
	}
worldy 2020-10-30
  • 打赏
  • 举报
回复
为什么要这么麻烦? 用一个变量轮询生成数据,直接写入ODR不是更直接? //测试OUT能否循环输出

27,374

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧