STM8配置GPIO输入输出功能

STM8开发参考:
    芯片寄存器文档
    原理图
    Google

 

1.GPIO工作模式
    输入:
        浮空输入
        上拉输入
    输出:
        推挽输出
        开漏输出
(1).浮空输入:浮空输入,可以做KEY识别,RX1
(2).带上拉输入:IO内部上拉电阻输入
(3).开漏输出:IO输出0接GND,IO输出1,悬空,需要外接上拉电阻,才能实现输出高电平。当输出为1时,IO口的状态由上拉电阻拉高电平,但由于是开漏输出模式,这样IO口也就可以由外部电路改变为低电平或不变。
(4).推挽输出:IO输出0-接GND,IO输出1 -接VCC,读输入值是未知的

2.软件配置
    参考:STM8S中文书据手册、原理图、google
    初始化流程:
        cpu时钟初始化
        IO输入输出选择
        IO模式选择
        IO输出/输入电平

    (1).CPU时钟初始化(所有STM8工程,都需要先设置时钟)
        内部时钟寄存器(CLK_ICKR):
            高速内部RC振荡器使能
            高速内部振荡器准备就绪
                CLK_ICKR = 0x03;
            时钟分频寄存器(CLK_CKDIVR):
                CLK_CKDIVR = 0x01; //cpu work on  16/2=8MHz

    (2).IO寄存器配置
        a.IO输入输出选择:
        端口x数据方向 (Px_DDR): x可以是A/B/C/D, 分别代表端口A/B/C/D
        输入模式:

            Px_DDR = 0x00; //端口x全部设置为输入模式
        输出模式:
            
Px_DDR = 0x00; //端口x全部设置为输出模式

        b.IO模式选择:
        端口x控制寄存器1 (Px_CR1):
        输入模式:
             浮空输入:
Px_CR1 = 0x00; //端口x全部设置为浮空输入
             带上拉电阻输入:
Px_CR1 = 0xFF; //端口x全部设置为带上拉电阻
        输出模式:
             模拟开漏输出
Px_CR1 = 0x00; //端口x全部设置为模拟开漏输出
             推挽输出:
Px_CR1 = 0xFF; //端口x全部设置为推挽输出

        c.IO输入/输出电平:
        端口x输入寄存器 (Px_IDR):
              Input = Px_IDR & 1; //当Input 为0时,端口Px的第0位输入低电平
                                               //当Input 为1时,端口Px的第0位输入高电平
         端口x输出数据寄存器(Px_ODR):
             
Px_ODR |= 0xFF; //端口x全部输出高电平
             
Px_ODR &= 0xFF; //端口x全部输出低电平

3.附上源码

    1.main.c
 

/* MAIN.C file
 * 
 * Copyright (c) 2002-2005 STMicroelectronics
 */

#include <stdio.h>
#include "stm8s_type.h"
#include "stm8s103f.h"
#include "stm8s.h"

#include "gpio.h"


//test gpio
void test_gpio(void)
{
	TGpioProperty Portx;

	//PD3 上拉输出 低电平设置 
	Portx.port = PORTD;	//选中端口
	Portx.dir = 1;		//输入、输出选择
	Portx.mode = 1;		//模式选择
	Portx.index = 3;	//端口那个
	Portx.outlevel = 0;	//输出时电平选择,输入模式无效

	init_Pxx_as_gpio(Portx);

	Portx.outlevel = 1;
	set_Pxx_level(Portx);
}


int main(void)
{

	bool PD3_level = 0;
	TGpioProperty Portx;

	CLK_ICKR = 0x03; /// open interval RTC and wakeup
	/// set cpu freq.
	CLK_CKDIVR = 0x00;		//cpu work on  16MHz

	delay_us(5000);



	//test gpio
	test_gpio();


	Portx.port = PORTD;
	Portx.dir = 0;
	Portx.mode = 1;
	Portx.index = 3;
	Portx.outlevel = 0;

	init_Pxx_as_gpio(Portx);

	while (1)
	{
		PD3_level = get_Pxx_level(Portx);

		if(PD3_level)
		{
			
		}
		else
		{
			
		}
		delay_us(1000000);
	}
}


    2.gpio.c

/*
 * gpio.c
 *
 *  Created on: Oct 25, 2019
 *      Author: 
 *		Email : 
 */

#include "stm8s.h"
#include "stm8s103f.h"
#include "gpio.h"


//GPIO输入输出
#define PADIR(dir, index)	{dir == 0? (PA_DDR &= ~(1<<index)): (PA_DDR |= (1<<index));}
#define PBDIR(dir, index)	{dir == 0? (PB_DDR &= ~(1<<index)): (PB_DDR |= (1<<index));}
#define PCDIR(dir, index)	{dir == 0? (PC_DDR &= ~(1<<index)): (PC_DDR |= (1<<index));}
#define PDDIR(dir, index)	{dir == 0? (PD_DDR &= ~(1<<index)): (PD_DDR |= (1<<index));}

//GPIO模式选择
#define PAMODE(mode, index)	{mode == 0? (PA_CR1 &= ~(1<<index)): (PA_CR1 |= (1<<index));}
#define PBMODE(mode, index)	{mode == 0? (PB_CR1 &= ~(1<<index)): (PB_CR1 |= (1<<index));}
#define PCMODE(mode, index)	{mode == 0? (PC_CR1 &= ~(1<<index)): (PC_CR1 |= (1<<index));}
#define PDMODE(mode, index)	{mode == 0? (PD_CR1 &= ~(1<<index)): (PD_CR1 |= (1<<index));}

//输出电平设置
#define PA_OLEVEL(dir, index, level)	{dir == 1? (level == 0? (PA_ODR &= ~(1<<index)): (PA_ODR |= (1<<index))): PA_IDR;}
#define PB_OLEVEL(dir, index, level)	{dir == 1? (level == 0? (PB_ODR &= ~(1<<index)): (PB_ODR |= (1<<index))): PB_IDR;}
#define PC_OLEVEL(dir, index, level)	{dir == 1? (level == 0? (PC_ODR &= ~(1<<index)): (PC_ODR |= (1<<index))): PC_IDR;}
#define PD_OLEVEL(dir, index, level)	{dir == 1? (level == 0? (PD_ODR &= ~(1<<index)): (PD_ODR |= (1<<index))): PD_IDR;}

//输入电平设置
#define PA_ILEVEL(index)	(PA_IDR & (1<<index))
#define PB_ILEVEL(index)	(PB_IDR & (1<<index))
#define PC_ILEVEL(index)	(PC_IDR & (1<<index))
#define PD_ILEVEL(index)	(PD_IDR & (1<<index))

void init_Pxx_as_gpio(TGpioProperty Portx)
{
	switch(Portx.port)
	{
		case PORTA:
			PADIR(Portx.dir, Portx.index);
			PAMODE(Portx.mode, Portx.index);
			PA_OLEVEL(Portx.dir, Portx.index, Portx.outlevel);
			break;
		case PORTB:
			PBDIR(Portx.dir, Portx.index);
			PBMODE(Portx.mode, Portx.index);
			PB_OLEVEL(Portx.dir, Portx.index, Portx.outlevel);
			break;
		case PORTC:
			PCDIR(Portx.dir, Portx.index);
			PCMODE(Portx.mode, Portx.index);
			PC_OLEVEL(Portx.dir, Portx.index, Portx.outlevel);
			break;
		case PORTD:
			PDDIR(Portx.dir, Portx.index);
			PDMODE(Portx.mode, Portx.index);
			PD_OLEVEL(Portx.dir, Portx.index, Portx.outlevel);
			break;
		default:
			break;
	}
}

void set_Pxx_level(TGpioProperty Portx)
{
	switch(Portx.port)
	{
		case PORTA:
			PA_OLEVEL(Portx.dir, Portx.index, Portx.outlevel);
			break;
		case PORTB:
			PB_OLEVEL(Portx.dir, Portx.index, Portx.outlevel);
			break;
		case PORTC:
			PC_OLEVEL(Portx.dir, Portx.index, Portx.outlevel);
			break;
		case PORTD:
			PD_OLEVEL(Portx.dir, Portx.index, Portx.outlevel);
			break;
		default:
			break;
	}
}

bool get_Pxx_level(TGpioProperty Portx)
{
	bool level = 0;;

	switch(Portx.port)
	{
		case PORTA:
			level = PA_ILEVEL(Portx.index);
			break;
		case PORTB:
			level = PB_ILEVEL(Portx.index);
			break;
		case PORTC:
			level = PC_ILEVEL(Portx.index);
			break;
		case PORTD:
			level = PD_ILEVEL(Portx.index);
			break;
		default:
			break;
	}

	return level;
}

    3.gpio.h

/*
 * gpio.h
 *
 *  Created on: Oct 25, 2019
 *      Author: 
 *		Email : 
 */

#ifndef DEVICE_GPIO_GPIO_H_
#define DEVICE_GPIO_GPIO_H_

#include <stdbool.h>

#define INPUT	0
#define OUTPUT	1

#define LOW_LEVEL	0
#define HIGHT_LEVEL	1

#define	PushPullOutput		1
#define	OpenDrainOutput		0
#define	PullUpInput			1
#define	FloatingiInput		0

typedef enum {
	PORTA = 0,
	PORTB = 1,
	PORTC = 2,
	PORTD = 3
}PORTx;


typedef struct _gpio_property
{
	PORTx	port;	//A~D
	bool	dir;	//INPUT 0, OUTPUT 1
	unsigned char mode;	//输入:上拉输入1   浮空输入 0;  输入:开漏输出0   推挽输出1
	unsigned char index; //端口下标
	unsigned char outlevel; //输出时电平选择,输入模式无效
}TGpioProperty, *PGpioProperty;


void init_Pxx_as_gpio(TGpioProperty Portx);
void set_Pxx_level(TGpioProperty Portx);
bool get_Pxx_level(TGpioProperty Portx);

#endif /* DEVICE_GPIO_GPIO_H_ */

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值