基于DM3730芯片的GPIO口配置方法和C程序例程
最近在做项目的时候用到了德州仪器的dm3730芯片,采用的开发板是Embest公司的devkit8500开发板。由于刚刚接触嵌入式不久,调试过程也是用了比较长的时间,下面贴出调试的过程和相关代码。
这块开发板自带的扩展接口中包含了大量的扩展GPIO口,如下图所示:
以gpio136为例。想要用程序实现io口输入输出的变化,需要先修改开发板的pinmux的配置。
对应CPU中的datasheet,可以寻找到每个引脚的配置。
其中,需要让gpio136功能开启的话,需要将其设置为M4模式,在M4模式下,才能实现GPIO136的功能,所以定位到开发板配置文件的
u-boot-03.00.02.07/board/timll/devkit8500/devkit8500.h下,
如图所示,GPIO136对应的功能模式代码修改成M4之后,编译内核,引导代码等等启动代码,导入开发板启动。
GPIO的启动关闭配置等等基本代码如下:
int gpio_export(unsigned int gpio) // 配置IO口
int gpio_unexport(unsigned int gpio) //注销IO口
int gpio_set_dir(unsigned int gpio, unsigned int out_flag) //设置输入输出方向
int gpio_set_value(unsigned int gpio, unsigned int value) //设置输出值
int gpio_get_value(unsigned int gpio, unsigned int *value) // 取得输入值
int gpio_set_edge(unsigned int gpio, char *edge) //设置边沿
int gpio_fd_open(unsigned int gpio)
int gpio_fd_close(int fd)
最终,为了模拟电机的PWM信号,本人依据上述代码编写了一段用gpio136引脚实现的模拟PWM波信号程序,在PC-Linux环境下编译后,拷贝到开发板上运行,最终用示波器读到了类似PWM信号,实现了该引脚的GPIO配置功能。以下是全部代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
/****************************************************************
* Constants
****************************************************************/
#define SYSFS_GPIO_DIR "/sys/class/gpio"
#define POLL_TIMEOUT (3 * 1000) /* 3 seconds */
#define MAX_BUF 64
/****************************************************************
* gpio_export
****************************************************************/
int gpio_export(unsigned int gpio)
{
int fd, len;
char buf[MAX_BUF];
fd = open(SYSFS_GPIO_DIR "/export", O_WRONLY);
if (fd < 0) {
perror("gpio/export");
return fd;
}
len = snprintf(buf, sizeof(buf), "%d", gpio);
write(fd, buf, len);
close(fd);
return 0;
}
/****************************************************************
* gpio_unexport
****************************************************************/
int gpio_unexport(unsigned int gpio)
{
int fd, len;
char buf[MAX_BUF];
fd = open(SYSFS_GPIO_DIR "/unexport", O_WRONLY);
if (fd < 0) {
perror("gpio/export");
return fd;
}
len = snprintf(buf, sizeof(buf), "%d", gpio);
write(fd, buf, len);
close(fd);
return 0;
}
/****************************************************************
* gpio_set_dir
****************************************************************/
int gpio_set_dir(unsigned int gpio, unsigned int out_flag)
{
int fd, len;
char buf[MAX_BUF];
len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/direction", gpio);
fd = open(buf, O_WRONLY);
if (fd < 0) {
perror("gpio/direction");
return fd;
}
if (out_flag)
write(fd, "out", 4);
else
write(fd, "in", 3);
close(fd);
return 0;
}
/****************************************************************
* gpio_set_value
****************************************************************/
int gpio_set_value(unsigned int gpio, unsigned int value)
{
int fd, len;
char buf[MAX_BUF];
len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
fd = open(buf, O_WRONLY);
if (fd < 0) {
perror("gpio/set-value");
return fd;
}
if (value)
write(fd, "1", 2);
else
write(fd, "0", 2);
close(fd);
return 0;
}
/****************************************************************
* gpio_get_value
****************************************************************/
int gpio_get_value(unsigned int gpio, unsigned int *value)
{
int fd, len;
char buf[MAX_BUF];
char ch;
len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
fd = open(buf, O_RDONLY);
if (fd < 0) {
perror("gpio/get-value");
return fd;
}
read(fd, &ch, 1);
if (ch != '0') {
*value = 1;
} else {
*value = 0;
}
close(fd);
return 0;
}
/****************************************************************
* gpio_set_edge
****************************************************************/
int gpio_set_edge(unsigned int gpio, char *edge)
{
int fd, len;
char buf[MAX_BUF];
len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/edge", gpio);
fd = open(buf, O_WRONLY);
if (fd < 0) {
perror("gpio/set-edge");
return fd;
}
write(fd, edge, strlen(edge) + 1);
close(fd);
return 0;
}
/****************************************************************
* gpio_fd_open
****************************************************************/
int gpio_fd_open(unsigned int gpio)
{
int fd, len;
char buf[MAX_BUF];
len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
fd = open(buf, O_RDONLY | O_NONBLOCK );
if (fd < 0) {
perror("gpio/fd_open");
}
return fd;
}
/****************************************************************
* gpio_fd_close
****************************************************************/
int gpio_fd_close(int fd)
{
return close(fd);
}
/****************************************************************
* Main
****************************************************************/
int main(int argc, char **argv, char **envp)
{
int i=50000;
gpio_export(136);
gpio_set_dir(136,1);
while(i)
{
gpio_set_value(136,1);
i--;
}
i=50000;
while(i)
{
gpio_set_value(136,0);
i--;
}
i=50000;
while(i)
{
gpio_set_value(136,1);
i--;
}
i=50000;
while(i)
{
gpio_set_value(136,0);
i--;
}
i=50000;
while(i)
{
gpio_set_value(136,1);
i--;
}
i=50000;
while(i)
{
gpio_set_value(136,0);
i--;
}
i=50000;
gpio_unexport(136);
return 0;
}
参考文章:
http://blog.****.net/davion_zhang/article/details/50463773
https://www.elinux.org/BeagleBoardPinMux