1、编写一个流水灯程序。已知,有8个LED灯(LED0~7)分别连接到S5PV210引脚的GPA0_0~7。当这些引脚高电平的时候,LED灯亮,反之则灭;两个按键(KEY0,KEY1)分别连接到引脚的GPH0_0, GPH0_1。当按下按键KEY0时,实现LED0->LED1->…->LED7 ->LED0的亮灯循环;当按下按键KEY1时,实现LED0->LED7->…->LED1->LED0的亮灯循环。现启动汇编代码start.S已有,请写出包括引脚初始化在内的其他C语言代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| #define GPA0CON *((volatile unsigned long *)0xE0200000) #define GPA0DAT *((volatile unsigned long *)0xE0200004)
#define GPH0CON *((volatile unsigned long *)0xE0200C00) #define GPH0DAT *((volatile unsigned long *)0xE0200C04)
#define GPA0_0_out (1<<(0*4)) #define GPA0_1_out (1<<(1*4)) #define GPA0_2_out (1<<(2*4)) #define GPA0_3_out (1<<(3*4)) #define GPA0_4_out (1<<(4*4)) #define GPA0_5_out (1<<(5*4)) #define GPA0_6_out (1<<(6*4)) #define GPA0_7_out (1<<(7*4))
int delay(int time) { int i,j; for(i = 0; i < time; i++) { for(j = 0;j < 0xfffff; j++); } return 0; }
int main() { int key_val = 0; int bit; GPA0CON &= ~0xFFFFFFFF; GPA0CON |= (GPA0_0_out | GPA0_1_out | GPA0_2_out | GPA0_3_out | GPA0_4_out | GPA0_5_out | GPA0_6_out | GPA0_7_out );
GPA0DAT &= ~(0xFF << 0);
GPH0CON &= ~(0xFF << 0);
while (1) { key_val = GPH0DAT & 0x3;
if (key_val) { delay(500000); key_val = GPH0DAT & 0x3;
if (key_val) { if (0x01 == key_val){
for(int i = 0; i < 8; i++) { GPA0DAT = GPA0DAT ^ (1 << i); delay(100); } } else if (0x02 == key_val){
for(int i = 7; i >= 0; i--) { GPA0DAT = GPA0DAT ^ (1 << i); delay(100); } } } } } return 0; }
|
2、编写一个串口数据接收程序。已知S5PV210默认选PCLK为时钟源,且PCLK为66MHz(即此题不需要编写PCLK的初始化程序)。请初始化串口UART0,即让UART0的波特率为115200,正常模式(非红外模式),以中断或轮询模式发生数据,并选择PCLK为串口时钟源,8位数据位,1位停止位,无校验位。然后让UART0串口不断的接收其他设备发送的数据。当接收到的一个字节的数据为0x0f时,引脚GPH0_0为高电平,以让LED0点亮,同时让引脚GPH0_1为低电平;当接收到的一个字节的数据为0xf0时,引脚GPH0_1为高电平,以让LED1点亮,同时让引脚GPH0_0为低电平。现启动汇编代码start.S已有,请写出包括初始化函数在内的其他C语言代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
| #define GPH0CON *((volatile unsigned int *)0xE0200C00) #define GPH0DAT *((volatile unsigned int *)0xE0200C04)
#define ULCON0 *((volatile unsigned int *)0xE2900000) #define UCON0 *((volatile unsigned int *)0xE2900004) #define UFCON0 *((volatile unsigned int *)0xE2900008) #define UTRSTAT0 *((volatile unsigned int *)0xE2900010) #define UTXH0 *((volatile unsigned int *)0xE2900020) #define URXH0 *((volatile unsigned int *)0xE2900024) #define UBRDIV0 *((volatile unsigned int *)0xE2900028) #define UDIVSLOT0 *((volatile unsigned int *)0xE290002C)
void uart0_init(void) {
GPA0CON &= ~0xFF;
GPA0CON |= 0x22;
ULCON0 = (0x3<<0) | (0<<2) | (0<<3) | (0<<6);
UCON0 = (1<<0) | (1<<2) | (1<<6) | (0<<10);
UFCON0 = 0;
UBRDIV0 = 34; UDIVSLOT0 = 0XDDDD; return; }
void putc(unsigned char c) { while (! (UTRSTAT0 & (1 << 2)) ); UTXH0 = c; return; }
unsigned char getc(void) { while (!(UTRSTAT0 & (1 << 0)) ); return (URXH0); }
#define GPH0_0_out (1<<(0*4)) #define GPH0_1_out (1<<(1*4))
#define GPH0_0_MASK (0xF<<(0*4)) #define GPH0_1_MASK (0xF<<(1*4))
extern void uart0_init(void);
int main(void) { char c;
while (1) { uart0_init(); c = getc(); putc(c);
GPH0CON &= ~(GPH0_0_MASK | GPH0_1_MASK);
GPH0CON |= (GPH0_0_out | GPH0_1_out);
GPH0DAT &= ~(0x3<<0);
if (c == 0X0F){ GPH0DAT &= 0 << 1; GPH0DAT |= 1 << 0; }
else if (c == 0XF0){ GPH0DAT &= 0 << 0; GPH0DAT |= 1 << 1; }
} return 0; }
|
3.编写一个稳压电源的控制程序。以下是稳压电源的示意图。高速AD在电压采集的时候,BUSY引脚为低电平,当模数转换完毕时,BUSY引脚为高电平,要求S5PV210采用查询BUSY引脚的方式里判断其是否转换完毕,然后再读取AD数据。电源驱动和可变负载部分,由于负载上的电压不稳定,所以需要S5PV210输出频率为100KHz(100000Hz)的PWM波来稳定输出电压,即根据其占空比稳定负载上的电压值。现要求S5PV210以10us的间隔进行AD的电压采集,并根据读取数据设定PWM的占空比,读取数据和占空比之间的换算方式如下:
占空比=(读取数据)/ 256
即当读取的数据为0x80时,占空比设定50%。
已知S5PV210默认选PCLK_PSYS为定时器0的时钟源,且已知PCLK_PSYS为66.7MHz(即此题不需要编写PCLK的初始化程序)。现启动汇编代码start.S已有,请写出包括定时器初始化函数、中断初始化函数、中断服务函数等在内的其他C语言代码,并给与代码注释。其中占空比的比例值、PWM波的频率值100KHz等设置上允许有误差。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
void time0_init(void){ TCFG0 |= 40; TCFG1 = 0x04; TCNTB0 = 100609; TCMPB0 = 50304;
TCON |= (1 << 1); TCON = 0x09; }
extern void IRQ_handle(void);
void init_irq(void) { TINT_CSTAT |= (1 << 1); }
void clear_irq(void) { TINT_CSTAT |= (1 << 5); }
void init_int(void) { VIC0INTSELECT |= ~(1 << 22); VIC0ADDRESS = 0x0; VIC0VECTADDR21 = (int)IRQ_handle; VIC0INTENABLE |= (1 << 22); }
void clear_vectaddr() { VIC0ADDRESS = 0X0; }
unsigned long get_irqstatus(void) { return VIC0IRQSTATUS; }
void irq_handler() { voliatile unsigned char status = ( (get_irqstatus() & (1 << 21) ) >> 21) & 0x1; clear_vecaddr(); clear_irq(); if(status == 0x1) { time0_init(); } }
int main(void) { GPA0CON &= ~0xFFFFFFFF; GPD0CON &= ~0xFF; GPD0CON |= 1; while(1){ while(!(GPD0DAT &= (1 << 0))){ time0_init(); } init_irq(); init_int(); }
}
|