led灯点亮

来源:互联网 发布:江西师大网络教学平台 编辑:程序博客网 时间:2024/05/02 15:24



手工点亮led arm汇编

start_led:mov r0,#8mov r1,#0bl  _gpio_direction_outputmov r1,#0x500000delayloop:nop    sub     r1,r1,#1cmp     r1,#0    bne delayloopmov r0,#8mov r1,#1bl  _gpio_direction_outputnop mov r1,#0x500000delayloop2:nop    sub     r1,r1,#1cmp     r1,#0    bne delayloop2  /*  bl _arm_blink_led*/    b start_led

C点亮led


int _arm_blink_led(){                 __asm__ __volatile__ ("start_led:\n\t""mov r0,#8\n\t""mov r1,#0\n\t""bl  _gpio_direction_output\n\t""mov r1,#0x500000\n\t""delayloop:\n\t""nop\n\t"    "sub     r1,r1,#1\n\t""cmp     r1,#0\n\t"    "bne delayloop\n\t""mov r0,#8\n\t""mov r1,#1\n\t""bl  _gpio_direction_output\n\t""nop\n\t""mov r1,#0x500000\n\t""delayloop2:\n\t""nop\n\t"    "sub     r1,r1,#1\n\t""cmp     r1,#0\n\t"    "bne delayloop2\n\t"     "b start_led\n\t"            );}



while(1);灯灭for (i=0,init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr,i++) {                if ((*init_fnc_ptr)() != 0) {            hang ();        }                if(i==0)while(1);//灯灭        if(i==1)while(1);//灯亮void start_armboot (void){    init_fnc_t **init_fnc_ptr;    char *s;    int i;#ifndef CFG_NO_FLASH    ulong size;#endif#if defined(CONFIG_VFD) || defined(CONFIG_LCD)    unsigned long addr;#endif    /* Pointer is writable since we allocated a register for it */    gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));    /* compiler optimization barrier needed for GCC >= 3.4 */    __asm__ __volatile__("": : :"memory");    memset ((void*)gd, 0, sizeof (gd_t));    gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));    memset (gd->bd, 0, sizeof (bd_t));    monitor_flash_len = _bss_start - _armboot_start;            gpio_direction_output(8, 0);    //while(1);灯亮} 


start.s 调用c的方法

X:\c300\uboot\board\mindspeed\c300v2evm\board.c
int _gpio_direction_output(unsigned gpio, int level){ gpio_direction_output(gpio,level); return 0;}X:\c300\uboot\include\asm\arch\comcerto-300.h#ifndef __ASSEMBLY__#include <asm/types.h>void comcerto300_init(void);int comcerto300_set_fcs(int enable, u8 cs, int base_addr, int size);int comcerto300_set_cs_type(u8 cs, int sdram_enable);int comcerto300_set_cs_region(u8 cs, u32 base, u32 size);int comcerto300_set_cse(u8 cs, int enable);void comcerto300_set_cse_highmem_to_cs1(int enable);int comcerto300_uexp_cfg_cs(u8 cs, u16 cfga, u16 cfgb, u16 cfgc);void comcerto300_pll_set_clocks(u32 arm_clock, u32 bus_clock, u32 spu_clock);void comcerto300_pll_set_arm_clock(u16 clkf, u16 clkr, u16 clkod);void comcerto300_pll_set_spu_clock(u16 clkf, u16 clkr, u16 clkod);void comcerto300_pll_set_amba_clock(u16 clkf, u16 clkr, u16 clkod);void comcerto300_ntg_8mhz_init(void); int _gpio_direction_output(unsigned gpio, int level);#endifX:\c300\uboot\cpu\arm1136\start.S mov r0,#8 mov r1,#0 bl _gpio_direction_outputffff: b ffff


int board_init(void){    /* reset on-board peripherals via GPIO line */    gpio_direction_output(CFG_GPIO_OUT_PERIPHERAL_RESET, 0);    while(1);    udelay(100);    gpio_set_value(CFG_GPIO_OUT_PERIPHERAL_RESET, 1);    /* CS0 is used for SDRAM, see bsp_init() */    /* CS1 and CS2 used for flash memories  */    nor_init();



static int __init mru_init(void){if(misc_register(&misc)){printk(KERN_ERR "failed to register mru\n");return -1;}mru_led_enable = 0;mru_led_stat = 0;gpio_direction_output(MRU_STAT_PIN, mru_led_stat);setup_timer(&mru_timer, mru_timer_proc, (unsigned long)&mru_timer);mod_timer(&mru_timer, jiffies + msecs_to_jiffies(50));printk(KERN_INFO "register mru\n");return 0;}static void mru_timer_proc(unsigned long data){    if(mru_led_enable && ++mru_led_count >= 10){        mru_led_count = 0;        mru_led_stat = !mru_led_stat;        gpio_set_value(MRU_STAT_PIN, mru_led_stat);    }        mod_timer((struct timer_list*)data, jiffies + msecs_to_jiffies(50));}
在linux驱动中常常会碰到gpio_set_value(port_num,0/1)或gpio_direction_output (port_num,0/1) 这两者有什么关系呢gpio_set_value(port_num,0/1) 一般只是在这个GPIO口的寄存器上写上某个值,至于这个端口是否设置为输出,它就管不了!而gpio_direction_output (port_num,0/1),在某个GPIO口写上某个值之后,还会把这个端口设置为输出模式。 因此,有人也许就会建议,把gpio_set_value这个函数直接去掉不用,是否可以,显然是可以的。 但是为什么系统还要用呢, 我个人分析是, 系统开发人员在要结合这两者来使用,以便提高效率。 一般某个端口设置好了输入与输出模式后,最好不要经常变动。 首先要调用gpio_direction_output(),以后要设置高低电平时,直接使用gpio_set_value()就可以了,这样可以省却再次调用设置输出模式的操作,从而提高运行效率!
Control and status reporting for the GPIO resources is provided through nine registers. The base address for the
GPIO control registers is mapped to 0x10070000. The GPIO control registers can be accessed by adding the
associated “Offset” to the GPIO base address.

54r32GPIO中断状态寄存器  54w GPIO中断状态寄存器清除        58RW 中断屏蔽寄存器00 禁止中断5cRW Watchdog Timer to GPIO Select Register
(default: ‘0’)0 64rw Bootstrap Pin Override Register
(default : all ‘0’). The control bits in this
register allow the programmer to
override the bootstrap pins on the device.                                




0RW32GPIO 写缺省全0 4rw32GPIO写使能缺省全01 输出使能 0 输入使能8RW 上升沿中断使能缺省01使能(仅当电平中断使能没有配置)cRW 下降沿中断使能01使能10R 输入寄存器 表示每个管脚的状态18RW 复用配置寄存器0 1cR 系统状态寄存器 0
Status of ARAMBOOT_n pin
In Normal Mode, EPROM = H and ARAMBOOT= L enable boot
from internal ARAM.28RW tdm复用控制寄存器"0010000_00000000 34RW DDR SSTL Buffer Type Register(default: “00000000_00000001”) 50RW 电平中断使能寄存器01 使能


0 0