lowlevel_init.S注解

 #include <config.h>
#include <version.h>

 

/* some parameters for the board */
 
/*
 *
 * Taken from linux/arch/arm/boot/compressed/head-s3c2410.S
 *
 * Copyright (C) 2002 Samsung Electronics SW.LEE  <hitchcar@sec.samsung.com>
 *
 */
@我的开发板上的SDRAM为:HY57V561620FTP-H,4Mx16bitx4Banks,两片接成32bit,64MB,接在BANK6上,地址范围为:[0x30000000-0x33ffffff]
@(还没搞清楚SDRAM的结构,为什么要分成Banks,改天看下相关的文档研究一下)
@对于SDRAM的初始化是要配置13个寄存器,好像多采用循环方式。
 
#define BWSCON 0x48000000
@BWSCON寄存器地址,控制每个总线
 
/* BWSCON */
#define DW8   (0x0)
#define DW16   (0x1)
#define DW32   (0x2)
@将用来设置位宽的三个宏
#define WAIT   (0x1<<2)
#define UBLB   (0x1<<3)
@将用来设置wait和ublb的宏
 
#define B1_BWSCON  (DW32)
#define B2_BWSCON  (DW16)
#define B3_BWSCON  (DW16 + WAIT + UBLB)
#define B4_BWSCON  (DW16)
#define B5_BWSCON  (DW16)
@BANK2、BANK3、BANK4、BANK5为什么配成16bit总线宽度,而且BANK3还要加上WAIT和UBLB属性没有搞明白,感觉如果没用到的话可以配成默认值的吧?
#define B6_BWSCON  (DW32)
#define B7_BWSCON  (DW32)
@我板子的SDRAM接在BANK6,所以配成32bit位宽,BANK7按datasheet的要求配置的和BANK6相同
 
@分别配置每个BANK的BANKCON寄存器,这里应该根据SRAM的手册来配置相应的BANK,BANK0~5主要是配置一些时序参数
/* BANK0CON */
#define B0_Tacs   0x0 /*  0clk */
#define B0_Tcos   0x0 /*  0clk */
#define B0_Tacc   0x7 /* 14clk */
#define B0_Tcoh   0x0 /*  0clk */
#define B0_Tah   0x0 /*  0clk */
#define B0_Tacp   0x0
#define B0_PMC   0x0 /* normal */
 
/* BANK1CON */
#define B1_Tacs   0x0 /*  0clk */
#define B1_Tcos   0x0 /*  0clk */
#define B1_Tacc   0x7 /* 14clk */
#define B1_Tcoh   0x0 /*  0clk */
#define B1_Tah   0x0 /*  0clk */
#define B1_Tacp   0x0
#define B1_PMC   0x0
 
#define B2_Tacs   0x0
#define B2_Tcos   0x0
#define B2_Tacc   0x7
#define B2_Tcoh   0x0
#define B2_Tah   0x0
#define B2_Tacp   0x0
#define B2_PMC   0x0
 
@这里BANK3CON不为默认值,是因为在SMDK2410上BANK3上应该接了ROM
@根据我自己的板子,我把这里换成了默认值(根据vivi上的默认值修改的),不过要不是默认值的话应该也没有影响的吧?我的板子这里接了DM9000A
#define B3_Tacs   0x0 /*  0clk */
#define B3_Tcos   0x3 /*  4clk */
#define B3_Tacc   0x7 /* 14clk */
#define B3_Tcoh   0x1 /*  1clk */
#define B3_Tah   0x0 /*  0clk */
#define B3_Tacp   0x3     /*  6clk */
#define B3_PMC   0x0 /* normal */
 
#define B4_Tacs   0x0 /*  0clk */
#define B4_Tcos   0x0 /*  0clk */
#define B4_Tacc   0x7 /* 14clk */
#define B4_Tcoh   0x0 /*  0clk */
#define B4_Tah   0x0 /*  0clk */
#define B4_Tacp   0x0
#define B4_PMC   0x0 /* normal */
 
#define B5_Tacs   0x0 /*  0clk */
#define B5_Tcos   0x0 /*  0clk */
#define B5_Tacc   0x7 /* 14clk */
#define B5_Tcoh   0x0 /*  0clk */
#define B5_Tah   0x0 /*  0clk */
#define B5_Tacp   0x0
#define B5_PMC   0x0 /* normal */
 
@配置SDRAM的参数,BANK6和BANK7要配置成同样的值,需要查看SDRAM的datasheet
@当内存为ROM或SRAM时需要配置所有位,当为SDRAM时只要配置[0~3]
#define B6_MT   0x3 /* SDRAM */
@内存类型,默认为SDRAM
#define B6_Trcd   0x1
@RAS到CAS的延时
#define B6_SCAN   0x1 /* 9bit */
@列扫描数,在SDRAM手册上,有一句:C0~C8即为9列
 
#define B7_MT   0x3 /* SDRAM */
#define B7_Trcd   0x1 /* 3clk */
#define B7_SCAN   0x1 /* 9bit */
 
/* REFRESH parameter */
@SDRAM刷新参数,这个很重要,移植时要更改
#define REFEN   0x1 /* Refresh enable */
@默认为允许刷新
#define TREFMD   0x0 /* CBR(CAS before RAS)/Auto refresh */
@据说下面三个时间参数多是根据经验来设置
#define Trp   0x0 /* 2clk */
@RAS precharge Time
#define Trc   0x3 /* 7clk */
@根据S3C2440的datasheet为:Trc=Tsrc+Trp,但寄存器中要填入的是Tsrc,这里仿佛应该设为10个时钟才对?
#define Tchr   0x2 /* 3clk */
@SDRAM手册上没有找到这个时钟的定义
#define REFCNT   1113 /* period="15".6us, HCLK="60Mhz", (2048+1-15.6*60) */
@SDRAM刷新计数值,这个值比较重要,根据SDRAM的datasheet,(我使用的这款芯片在datasheet写着8192Refresh cycle/64ms,所以一个刷新周期为64ms/8192=7.8125us,取7.9的话REFCNT的值就为1259)
/**************************************/
 
_TEXT_BASE:
 .word TEXT_BASE
 
@这里开始lowlevel_init函数了,通过循环连续初始化13个寄存器
.globl lowlevel_init
lowlevel_init:
 /* memory control configuration */
 /* make r0 relative the current location so that it */
 /* reads SMRDATA out of FLASH rather than memory ! */
 ldr     r0, =SMRDATA
 ldr r1, _TEXT_BASE
@r1放代码段的开始位置
 sub r0, r0, r1
    //计算SMRDATA的相对地址保存到R0中
    //SMRDATA为虚拟地址,而TEXT_BASE为虚拟地址的起始地址
    //而现在Uboot的起始地址并不为虚拟地址
    //TEXT_BASE为0x33F8 0000,SMRDATA为0x33F8 06C8
    //而现在程序运行在起始地址为0x0000 0000的地方
    //所以需要计算以0x0000 0000为标准的相对地址
(参考uboot-1.3.0-rc3引导启动学习笔记,这一段确实要好好理解)
 ldr r1, =BWSCON /* Bus Width Status Controller */
 add     r2, r0, #13*4
@13个寄存器,每个寄存器占4个字节
@读取一个值存入寄存器中,然后循环,直到读完13个寄存器
0:
 ldr     r3, [r0], #4
 str     r3, [r1], #4
 cmp     r2, r0
 bne     0b
 
 /* everything is fine now */
 mov pc, lr
@程序返回到cpu_init_crit中
 
 .ltorg
/* the literal pools origin */
 
SMRDATA:
    .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
@设置每个BWSCON,注意BANK0由硬件连线决定了。
    .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
    .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
    .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
    .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
    .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
    .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
@设置BANKCON0~BANKCON5
    .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
    .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
@设置BANKCON6~BANKCON7
    .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
@设置REFRESH,在S3C2440中11~17位是保留的,也即(Tchr<<16)无意义
    .word 0x32
@设置BANKSIZE,对于容量可以设置大写,多出来的空内存会被自动检测出来。没有搞明白突发模式操作是什么意思!
    .word 0x30
@设置MRSRB6
    .word 0x30
@设置MRSRB7

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhulizhen/archive/2009/09/11/4541061.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include "main.h" #include "stdio.h" #include "string.h" #include "time.h" UART_HandleTypeDef huart1; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART1_UART_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART1_UART_Init(); while (1) { time_t now = time(NULL); struct tm *timeinfo = localtime(&now); char time_str[9]; sprintf(time_str, "%02d:%02d:%02d", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); HAL_UART_Transmit(&huart1, (uint8_t *)time_str, strlen(time_str), HAL_MAX_DELAY); HAL_Delay(1000); } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } } static void MX_USART1_UART_Init(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart1) != HAL_OK) { Error_Handler(); } } static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOA_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET); /*Configure GPIO pin : PA9 */ GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } 在以上代码的基础上,编写代码以实现计算发送 hh:mm:ss到单片机,修改单片机时间
05-30
可以使用串口接收单片机发送过来的时间数据,然后通过C语言中的time()函数来设置单片机的时间。下面是示例代码: ``` #include "main.h" #include "stdio.h" #include "string.h" #include "time.h" UART_HandleTypeDef huart1; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART1_UART_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART1_UART_Init(); // 用于接收单片机发送过来的时间数据 char time_input[9]; while (1) { // 接收串口数据 HAL_UART_Receive(&huart1, (uint8_t *)time_input, 9, HAL_MAX_DELAY); // 将接收到的时间数据转换成struct tm格式 struct tm timeinfo = {0}; sscanf(time_input, "%d:%d:%d", &timeinfo.tm_hour, &timeinfo.tm_min, &timeinfo.tm_sec); // 设置单片机时间 time_t now = mktime(&timeinfo); if(now != -1) { if(stm32_settime(now) == 0) { printf("Time set successfully!\r\n"); } else { printf("Failed to set time.\r\n"); } } else { printf("Invalid time data.\r\n"); } } } // 设置单片机时间 int stm32_settime(time_t t) { struct tm *timeinfo = localtime(&t); RTC_TimeTypeDef sTime = {0}; RTC_DateTypeDef sDate = {0}; sTime.Hours = timeinfo->tm_hour; sTime.Minutes = timeinfo->tm_min; sTime.Seconds = timeinfo->tm_sec; sDate.WeekDay = timeinfo->tm_wday; sDate.Month = timeinfo->tm_mon + 1; sDate.Date = timeinfo->tm_mday; sDate.Year = timeinfo->tm_year - 100; if(HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK) { return -1; } if(HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK) { return -1; } return 0; } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } } static void MX_USART1_UART_Init(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart1) != HAL_OK) { Error_Handler(); } } static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOA_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET); /*Configure GPIO pin : PA9 */ GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } ``` 同时,需要在单片机上添加RTC实时时钟模块,并在CubeMX中进行配置。需要注意的是,使用RTC模块前需要先初始化时钟,可以使用RCC_OscConfig和RCC_ClkConfig函数来进行初始化。在设置时间时,需要将时间数据转换成RTC模块所需的格式,并调用HAL_RTC_SetTime和HAL_RTC_SetDate函数来设置时间和日期。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值