OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5152|回复: 4

imx6ull 通过ioremap 方式操作IO无输出,有可能是什么问题,io配置已经反复确认了

[复制链接]

2

主题

3

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2014-4-25
在线时间
6 小时
发表于 2021-12-10 11:28:03 | 显示全部楼层 |阅读模式
1金钱
#include <linux/types.h>

#include <linux/kernel.h>

#include <linux/delay.h>

#include <linux/ide.h>

#include <linux/init.h>

#include <linux/module.h>

#include <linux/errno.h>

#include <linux/gpio.h>

#include <asm/mach/map.h>

#include <asm/uaccess.h>

#include <asm/io.h>

//#include <stdio.h>

/***************************************************************

Copyright &#169; ALIENTEK Co., Ltd. 1998-2029. All rights reserved.

文件名                : led.c

作者                  : 左忠凯

版本                   : V1.0

描述                   : LED驱动文件。

其他                   : 无

论坛                    : www.openedv.com

日志                   : 初版V1.0 2019/1/30 左忠凯创建

***************************************************************/

#define LED_MAJOR                200                /* 主设备号 */

#define LED_NAME                "led"         /* 设备名字 */



#define LEDOFF         0                                /* 关灯 */

#define LEDON         1                                /* 开灯 */



/* 寄存器物理地址 */

#define CCM_CCGR1_BASE                                (0X020C406C)       

#define SW_MUX_GPIO1_IO03_BASE                (0X020E0068)



#define SW_MUX_GPIO1_IO20_BASE                (0X020E0094)

#define SW_MUX_GPIO1_IO21_BASE                (0X020E0098)

#define SW_MUX_GPIO1_IO22_BASE                (0X020E009C)

#define SW_MUX_GPIO1_IO23_BASE                (0X020E00A0)

#define SW_MUX_GPIO1_IO24_BASE                (0X020E00A4)

#define SW_MUX_GPIO1_IO25_BASE                (0X020E00A8)

#define SW_MUX_GPIO1_IO26_BASE                (0X020E00AC)



#define SW_PAD_GPIO1_IO03_BASE                (0X020E02F4)



#define SW_PAD_GPIO1_IO20_BASE                (0X020E0320)

#define SW_PAD_GPIO1_IO21_BASE                (0X020E0324)

#define SW_PAD_GPIO1_IO22_BASE                (0X020E0328)

#define SW_PAD_GPIO1_IO23_BASE                (0X020E032C)

#define SW_PAD_GPIO1_IO24_BASE                (0X020E0330)

#define SW_PAD_GPIO1_IO25_BASE                (0X020E0334)

#define SW_PAD_GPIO1_IO26_BASE                (0X020E0338)



#define GPIO1_DR_BASE                                (0X0209C000)

#define GPIO1_GDIR_BASE                                (0X0209C004)

#define GPIO1_PSR_BASE                                (0X0209C008)



#define IO_SPI_CS    (1<<20)

#define IO_SPI_CLK   (1<<21)

#define IO_SPI_SDO   (1<<22)

#define IO_SPI_SDI   (1<<23)

#define IO_SPI_RESET (1<<26)

/* 映射后的寄存器虚拟地址指针 */

#define test0

#ifdef test0

static void __iomem *IMX6U_CCM_CCGR1;



static volatile void __iomem* SW_MUX_GPIO1_IO03;



static volatile void __iomem* SW_MUX_GPIO1_IO20;

static volatile void __iomem* SW_MUX_GPIO1_IO21;

static volatile void __iomem* SW_MUX_GPIO1_IO22;

static volatile void __iomem* SW_MUX_GPIO1_IO23;

static volatile void __iomem* SW_MUX_GPIO1_IO26;



static volatile void __iomem *SW_PAD_GPIO1_IO03;



static volatile void __iomem* SW_PAD_GPIO1_IO20;

static volatile void __iomem* SW_PAD_GPIO1_IO21;

static volatile void __iomem* SW_PAD_GPIO1_IO22;

static volatile void __iomem* SW_PAD_GPIO1_IO23;

static volatile void __iomem* SW_PAD_GPIO1_IO26;



static volatile void __iomem *GPIO1_DR;

static volatile void __iomem *GPIO1_GDIR;

static volatile void __iomem* GPIO1_PSR;

#else

static unsigned int *IMX6U_CCM_CCGR1;



static volatile unsigned int* SW_MUX_GPIO1_IO03;



static volatile unsigned int* SW_MUX_GPIO1_IO20;

static volatile unsigned int* SW_MUX_GPIO1_IO21;

static volatile unsigned int* SW_MUX_GPIO1_IO22;

static volatile unsigned int* SW_MUX_GPIO1_IO23;

static volatile unsigned int* SW_MUX_GPIO1_IO26;



static volatile unsigned int *SW_PAD_GPIO1_IO03;



static volatile unsigned int* SW_PAD_GPIO1_IO20;

static volatile unsigned int* SW_PAD_GPIO1_IO21;

static volatile unsigned int* SW_PAD_GPIO1_IO22;

static volatile unsigned int* SW_PAD_GPIO1_IO23;

static volatile unsigned int* SW_PAD_GPIO1_IO26;



static volatile unsigned int *GPIO1_DR;

static volatile unsigned int *GPIO1_GDIR;

static volatile unsigned int* GPIO1_PSR;

#endif

static struct class *ssd2828_class;



void SSD2828_write_pin(unsigned int pin,unsigned char state)

{

        #ifdef test0

        unsigned int val = 0;



        val = readl(GPIO1_DR);

        if (state > 0)

        {

                val |= pin;

        }

        else

        {

                val &= ~pin;

        }



        writel(val, GPIO1_DR);

        #else

        unsigned int val = 0;



        val = *GPIO1_DR;



        if (state > 0)

        {

                val |= pin;

        }

        else

        {

                val &= ~pin;

        }

        *GPIO1_DR = val;

        #endif

}

#define SSD2828_write_cs(state) SSD2828_write_pin(IO_SPI_CS,state)

#define SSD2828_write_clk(state) SSD2828_write_pin(IO_SPI_CLK,state)

#define SSD2828_write_sdo(state) SSD2828_write_pin(IO_SPI_SDO,state)

#define SSD2828_write_reset(state) SSD2828_write_pin(IO_SPI_RESET,state)

#if 0

void SSD2828_write_cs(unsigned char state)

{

        SSD2828_write_pin(IO_SPI_CS,state);

}



void SSD2828_write_clk(unsigned char state)

{

        SSD2828_write_pin(IO_SPI_CLK,state);

}





void SSD2828_write_sdo(unsigned char state)

{

        SSD2828_write_pin(IO_SPI_SDO,state);

}



void SSD2828_write_reset(unsigned char state)

{

        SSD2828_write_pin(IO_SPI_RESET,state);

}

#endif

unsigned char SSD2828_read_sdi(void)

{



        #ifdef test0

        unsigned int val = 0;



        val = readl(GPIO1_PSR);

        val &= IO_SPI_SDI;

        if (val > 0)

        {

                return 1;

        }

        else

        {

                return 0;

        }

        #else

        unsigned int val = 0;



        val = *GPIO1_PSR;

        val &= IO_SPI_SDI;

        if (val > 0)

        {

                return 1;

        }

        else

        {

                return 0;

        }

        #endif

}



void delay(int val)

{

        int i = 0;

        for (i = 0; i < val; i++)

        {

                ;

        }

}



/*

cmd 0  command  1data

*/

void SSD2828_Write_cmd(unsigned char data)

{

        unsigned char i = 0;

        //uint32_t temp = reg;



        //SSD2828_write_cs(0);

        SSD2828_write_clk(0);

        delay(20);



        SSD2828_write_sdo(0);

        delay(20);

        SSD2828_write_clk(1);

        delay(20);

       



        for (i = 0; i < 8; i++)

        {

                SSD2828_write_clk(0);

                delay(20);

                if (data & 0x80)

                        SSD2828_write_sdo(1);

                else

                        SSD2828_write_sdo(0);

                delay(20);



                SSD2828_write_clk(1);

                delay(20);

                data <<= 1;

        }

        SSD2828_write_clk(0);

        delay(20);

        //SSD2828_write_cs(1);

        //delay(20);

}



/*

cmd 0  command  1data

*/

void SSD2828_Write_bytes(unsigned char reg,unsigned char* data,int len)

{

        unsigned char i = 0,j=0;

        unsigned char val;



        //SSD2828_write_cs(0);

        SSD2828_write_clk(0);

        delay(20);



        SSD2828_write_sdo(1);

        delay(20);

        SSD2828_write_clk(1);

        delay(20);



        for (j = 0; j < len; j++)

        {

                val = data[j];

                for (i = 0; i < 8; i++)

                {

                        SSD2828_write_clk(0);

                        delay(20);

                        if (val & 0x80)

                                SSD2828_write_sdo(1);

                        else

                                SSD2828_write_sdo(0);

                        delay(20);



                        SSD2828_write_clk(1);

                        delay(20);

                        val <<= 1;

                }

        }

        SSD2828_write_clk(0);

        delay(20);

        //SSD2828_write_cs(1);

        //delay(20);

}



unsigned char SSD2828_Read_byte(void)

{

        unsigned char i = 0;

        unsigned char val = 0;



        SSD2828_write_clk(0);

        delay(20);



        for (i = 0; i < 8; i++)

        {

                val <<= 1;

                SSD2828_write_clk(0);

                delay(20);

                SSD2828_write_clk(1);

                delay(20);



                if (SSD2828_read_sdi() & 0x01)

                {

                        val |= 0x01;

                }

        }



        SSD2828_write_clk(0);

        delay(20);



        return val;

}



/*

* @description                : LED打开/关闭

* @param - sta         : LEDON(0) 打开LED,LEDOFF(1) 关闭LED

* @return                         : 无

*/

void led_switch(u8 sta)

{

        u32 val = 0;

        if(sta == LEDON) {

                val = readl(GPIO1_DR);

                val &= ~(1 << 3);       

                writel(val, GPIO1_DR);

        }else if(sta == LEDOFF) {

                val = readl(GPIO1_DR);

                val|= (1 << 3);       

                writel(val, GPIO1_DR);

        }       

}



/*

* @description                : 打开设备

* @param - inode         : 传递给驱动的inode

* @param - filp         : 设备文件,file结构体有个叫做private_data的成员变量

*                                           一般在open的时候将private_data指向设备结构体。

* @return                         : 0 成功;其他 失败

*/

static int led_open(struct inode *inode, struct file *filp)

{

        return 0;

}



/*

* @description                : 从设备读取数据

* @param - filp         : 要打开的设备文件(文件描述符)

* @param - buf         : 返回给用户空间的数据缓冲区

* @param - cnt         : 要读取的数据长度

* @param - offt         : 相对于文件首地址的偏移

* @return                         : 读取的字节数,如果为负值,表示读取失败

*/

static ssize_t led_read(struct file *filp, char __user *buf, size_t cnt, loff_t *offt)

{

        return 0;

}



/*

* @description                : 向设备写数据

* @param - filp         : 设备文件,表示打开的文件描述符

* @param - buf         : 要写给设备写入的数据

* @param - cnt         : 要写入的数据长度

* @param - offt         : 相对于文件首地址的偏移

* @return                         : 写入的字节数,如果为负值,表示写入失败

*/

static ssize_t led_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)

{

        int retvalue;

        unsigned char databuf[1];

        unsigned char ledstat;



        retvalue = copy_from_user(databuf, buf, cnt);

        if(retvalue < 0) {

                printk("kernel write failed!\r\n");

                return -EFAULT;

        }



        ledstat = databuf[0];                /* 获取状态值 */



        if(ledstat == LEDON) {       

                led_switch(LEDON);                /* 打开LED灯 */

        } else if(ledstat == LEDOFF) {

                led_switch(LEDOFF);        /* 关闭LED灯 */

        }

        return 0;

}



/*

* @description                : 关闭/释放设备

* @param - filp         : 要关闭的设备文件(文件描述符)

* @return                         : 0 成功;其他 失败

*/

static int led_release(struct inode *inode, struct file *filp)

{

        return 0;

}



/* 设备操作函数 */

static struct file_operations led_fops = {

        .owner = THIS_MODULE,

        .open = led_open,

        .read = led_read,

        .write = led_write,

        .release =         led_release,

};



/*

* @description        : 驱动出口函数

* @param                 : 无

* @return                 : 无

*/

static int __init led_init(void)

{

        unsigned char idl,idh;

        int retvalue = 0;

        //unsigned short id = 0;

        u32 val = 0;



        printk("%s  %s  %d\n",__FILE__,__FUNCTION__,__LINE__);

       

        retvalue = register_chrdev(LED_MAJOR, LED_NAME, &led_fops);

        if(retvalue < 0){

                printk("register chrdev failed!\r\n");

                return -EIO;

        }

       

        /* 初始化LED */

        /* 1、寄存器地址映射 */

          IMX6U_CCM_CCGR1 = ioremap(CCM_CCGR1_BASE, 4);



        SW_MUX_GPIO1_IO03 = ioremap(SW_MUX_GPIO1_IO03_BASE, 4);

          SW_PAD_GPIO1_IO03 = ioremap(SW_PAD_GPIO1_IO03_BASE, 4);



        SW_MUX_GPIO1_IO20 = ioremap(SW_MUX_GPIO1_IO20_BASE, 4);

        SW_PAD_GPIO1_IO20 = ioremap(SW_PAD_GPIO1_IO20_BASE, 4);



        SW_MUX_GPIO1_IO21 = ioremap(SW_MUX_GPIO1_IO21_BASE, 4);

        SW_PAD_GPIO1_IO21 = ioremap(SW_PAD_GPIO1_IO21_BASE, 4);



        SW_MUX_GPIO1_IO22 = ioremap(SW_MUX_GPIO1_IO22_BASE, 4);

        SW_PAD_GPIO1_IO22 = ioremap(SW_PAD_GPIO1_IO22_BASE, 4);



        SW_MUX_GPIO1_IO23 = ioremap(SW_MUX_GPIO1_IO23_BASE, 4);

        SW_PAD_GPIO1_IO23 = ioremap(SW_PAD_GPIO1_IO23_BASE, 4);



        SW_MUX_GPIO1_IO26 = ioremap(SW_MUX_GPIO1_IO26_BASE, 4);

        SW_PAD_GPIO1_IO26 = ioremap(SW_PAD_GPIO1_IO26_BASE, 4);



        GPIO1_DR = ioremap(GPIO1_DR_BASE, 4);

        GPIO1_GDIR = ioremap(GPIO1_GDIR_BASE, 4);

        GPIO1_PSR = ioremap(GPIO1_PSR_BASE, 4);

        /* 2、使能GPIO1时钟 */

        val = readl(IMX6U_CCM_CCGR1);

        val &= ~(3 << 26);        /* 清楚以前的设置 */

        val |= (3 << 26);        /* 设置新值 */



        writel(val, IMX6U_CCM_CCGR1);



        /* 3、设置GPIO1_IO03的复用功能,将其复用为

         *    GPIO1_IO03,最后设置IO属性。

         */

        writel(5, SW_MUX_GPIO1_IO03);

       

        writel(5, SW_MUX_GPIO1_IO20);

        writel(5, SW_MUX_GPIO1_IO21);

        writel(5, SW_MUX_GPIO1_IO22);

        writel(5, SW_MUX_GPIO1_IO23);

        writel(5, SW_MUX_GPIO1_IO26);

        /*寄存器SW_PAD_GPIO1_IO03设置IO属性

         *bit 16:0 HYS关闭

         *bit [15:14]: 00 默认下拉

     *bit [13]: 0 kepper功能

     *bit [12]: 1 pull/keeper使能

     *bit [11]: 0 关闭开路输出

     *bit [7:6]: 11 速度200Mhz

     *bit [5:3]: 110 R0/6驱动能力

     *bit [0]: 0 低转换率

         */

        writel(0x10f0, SW_PAD_GPIO1_IO03);



        /*寄存器SW_PAD_GPIO1_IO20设置IO属性  CS

         *bit 16:0 HYS关闭

         *bit [15:14]: 10 100K上拉

         *bit [13]: 0 kepper功能

         *bit [12]: 1 pull/keeper使能

         *bit [11]: 0 关闭开路输出

         *bit [7:6]: 11 速度200Mhz

         *bit [5:3]: 110 R0/6驱动能力

         *bit [0]: 0 低转换率

         */

        val = (1<<16)|(2 << 14) |(1 << 13)| (1 << 12) | (3 << 6) | (6 << 3)|(1<<0);

        writel(val, SW_PAD_GPIO1_IO20);



        /*寄存器SW_PAD_GPIO1_IO21设置IO属性  CLK

         *bit 16:0 HYS关闭

         *bit [15:14]: 00 100K下拉

         *bit [13]: 0 kepper功能

         *bit [12]: 1 pull/keeper使能

         *bit [11]: 0 关闭开路输出

         *bit [7:6]: 11 速度200Mhz

         *bit [5:3]: 110 R0/6驱动能力

         *bit [0]: 0 低转换率

         */

        val = (1<<16)|(0 << 14)| (1 << 13)|(1 << 12) | (3 << 6) | (6 << 3)|(1<<0);

        writel(val, SW_PAD_GPIO1_IO21);



        /*寄存器SW_PAD_GPIO1_IO22设置IO属性  SDO

         *bit 16:0 HYS关闭

         *bit [15:14]: 10 100K上拉

         *bit [13]: 0 kepper功能

         *bit [12]: 1 pull/keeper使能

         *bit [11]: 0 关闭开路输出

         *bit [7:6]: 11 速度200Mhz

         *bit [5:3]: 110 R0/6驱动能力

         *bit [0]: 0 低转换率

         */

        val = (1<<16)| (2 << 14) | (1 << 13)| (1 << 12) | (3 << 6) | (6 << 3)|(1<<0);

        writel(val, SW_PAD_GPIO1_IO22);



        /*寄存器SW_PAD_GPIO1_IO23设置IO属性  SDI

         *bit 16:0 HYS关闭

         *bit [15:14]: 10 100K上拉

         *bit [13]: 0 kepper功能

         *bit [12]: 1 pull/keeper使能

         *bit [11]: 0 关闭开路输出

         *bit [7:6]: 11 速度200Mhz

         *bit [5:3]: 110 R0/6驱动能力

         *bit [0]: 0 低转换率

         */

        val = (1<<16)|(2 << 14) | (1 << 13)|(1 << 12) | (3 << 6) | (6 << 3)|(1<<0);

        writel(val, SW_PAD_GPIO1_IO23);



        /*寄存器SW_PAD_GPIO1_IO22设置IO属性  SDO

         *bit 16:0 HYS关闭

         *bit [15:14]: 10 100K上拉

         *bit [13]: 0 kepper功能

         *bit [12]: 1 pull/keeper使能

         *bit [11]: 0 关闭开路输出

         *bit [7:6]: 11 速度200Mhz

         *bit [5:3]: 110 R0/6驱动能力

         *bit [0]: 0 低转换率

         */

        val = (1<<16)|(2 << 14) |(1 << 13)| (1 << 12) | (3 << 6) | (6 << 3)|(1<<0);

        writel(val, SW_PAD_GPIO1_IO26);



        /* 4、设置GPIO1_IO03为输出功能 */

        val = readl(GPIO1_GDIR);

        val &= ~(1 << 3);        /* 清除以前的设置 */



        val &= ~(1 << 20);        /* 清除以前的设置 */

        val &= ~(1 << 21);        /* 清除以前的设置 */

        val &= ~(1 << 22);        /* 清除以前的设置 */

        val &= ~(1 << 23);        /* 清除以前的设置 */



        val |= (1 << 3);        /* 设置为输出 */



        val |= (1 << 20);        /* 设置为输出 */

        val |= (1 << 21);        /* 设置为输出 */

        val |= (1 << 22);        /* 设置为输出 */

        val &= ~(1 << 23);        /* 设置为输入 */

        val |= (1 << 26);        /* 设置为输入 */

        writel(val, GPIO1_GDIR);



        /* 5、默认关闭LED */

        val = readl(GPIO1_DR);

        val |= (1 << 3);       



        val |= IO_SPI_CS; //cs 拉高

        val &= ~(IO_SPI_CLK); // clk 拉低

        //val |= (1 << 22);

        //val |= (1 << 3);

        writel(val, GPIO1_DR);



        SSD2828_write_cs(1);

        SSD2828_write_clk(0);



        SSD2828_write_reset(1);

        mdelay(50);

        SSD2828_write_reset(0);

        mdelay(50);

        SSD2828_write_reset(1);

        mdelay(50);



        SSD2828_write_cs(0);

        delay(20);

        SSD2828_Write_cmd(0xb0);

        SSD2828_Write_cmd(0xfa);

        SSD2828_Write_cmd(0x00);

        //buf[0] = SSD2828_Read_byte();

        //buf[1] = SSD2828_Read_byte();

        idl = SSD2828_Read_byte();

        idh = SSD2828_Read_byte();

        //printk("ssd2828 id is 0x%x 0x%x \n",buf[0],buf[1]);

        printk("---myid=0x%x,0x%x\n", idl, idh);

        /* 6、注册字符设备驱动 */
        //ssd2828_class = class_create(THIS_MODULE,LED_NAME);
        //device_create(ssd2828_class,NULL,MKDEV(LED_MAJOR,0),NULL,LED_NAME);

        return 0;

}



/*

* @description        : 驱动出口函数

* @param                 : 无

* @return                 : 无

*/
static void __exit led_exit(void)
{
        /* 取消映射 */

        iounmap(IMX6U_CCM_CCGR1);

        iounmap(SW_MUX_GPIO1_IO03);

        iounmap(SW_MUX_GPIO1_IO20);
        iounmap(SW_MUX_GPIO1_IO21);
        iounmap(SW_MUX_GPIO1_IO22);
        iounmap(SW_MUX_GPIO1_IO23);
        iounmap(SW_MUX_GPIO1_IO26 );

        iounmap(SW_PAD_GPIO1_IO03);

        iounmap(SW_PAD_GPIO1_IO20);
        iounmap(SW_PAD_GPIO1_IO21);
        iounmap(SW_PAD_GPIO1_IO22);
        iounmap(SW_PAD_GPIO1_IO23);
        iounmap(SW_PAD_GPIO1_IO26);

        iounmap(GPIO1_DR);
        iounmap(GPIO1_GDIR);
        iounmap(GPIO1_PSR);

        /* 注销字符设备驱动 */

        //device_destroy(ssd2828_class,MKDEV(LED_MAJOR,0));

        //class_destroy(ssd2828_class);

        unregister_chrdev(LED_MAJOR, LED_NAME);

}

module_init(led_init);

module_exit(led_exit);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("zuozhongkai");


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

592

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1458
金钱
1458
注册时间
2019-7-28
在线时间
137 小时
发表于 2021-12-10 17:24:18 | 显示全部楼层
帮顶                    
回复

使用道具 举报

13

主题

58

帖子

0

精华

初级会员

Rank: 2

积分
163
金钱
163
注册时间
2018-1-25
在线时间
38 小时
发表于 2023-1-2 18:51:11 | 显示全部楼层
同问,目前测了5个引脚,GPIO4上的2个引脚可以正常输出,GPIO1上的3个引脚没有输出。请问您解决了吗?
回复

使用道具 举报

13

主题

58

帖子

0

精华

初级会员

Rank: 2

积分
163
金钱
163
注册时间
2018-1-25
在线时间
38 小时
发表于 2023-1-2 18:53:48 | 显示全部楼层
使用gpio_set_value都是对的,就是ioremap之后,readl和writel就出现有的引脚无输出。
回复

使用道具 举报

13

主题

58

帖子

0

精华

初级会员

Rank: 2

积分
163
金钱
163
注册时间
2018-1-25
在线时间
38 小时
发表于 2023-1-3 11:05:44 | 显示全部楼层
测试总结:gpio_set_value和ioremap两种方法不能同时使用,原因不明。
总共25个IO,大部分分布在GPIO1和GPIO4。
刚开始用的gpio_set_value/gpio_get_value的方法进行通信,功能正常,但是感觉速度不够快,一次完整通信大概100us。
然后就改成了ioremap的方法,思路是逐步替换嘛,在功能正常的基础上,一个个的替换成ioremap,结果通信异常。
经过测试发现:当gpio_set_value和ioremap/writel同时使用的时候,端口电平不是预期的,把25个GPIO全部用ioremap和writel操作的话,功能就正常了。
但是速度也没有太大提升,由原来的100us提高到了50us。
总共才25个GPIO的操作,这个几十us的时间还是感觉不太对劲儿,目前也没有更好的思路深究了,欢迎指教。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-25 07:03

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表