Kamis, 30 Desember 2010

STM32 blink led using assembly

Semingguan coba belajar bahasa assembly buat ARM (thumb2), ternyata emang sangat susah.
Mayan dikit2 dah ngerti kalau buat debug yg codenya keluar assembler doang.
Program berikut cuma blink led setiap 500ms. Beberapa address masih di hard code (bad programming).




/* Includes */
#include
#include "stm32f10x.h"

/* define compiler specific symbols */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */

#elif defined ( __ICCARM__ )
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */

#elif defined ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */

#elif defined ( __TASKING__ )
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#define __INLINE inline /*!< inline keyword for TASKING Compiler */

#endif

__IO uint32_t TimingDelay;
void Delay(__IO u32 time)
{
TimingDelay = time;
while(TimingDelay!=0);
}

void TimingDelay_Decrement(void)
{
if (TimingDelay != 0x00)
{
TimingDelay--;
}
}


inline void ledLoop(void)
{
__ASM volatile("ldr r1,=0x40011000\n\t" //load GPIOC address
"ldr r2,=0x100\n\t" //load Pin_8
"ledloop:"

"str r2,[r1,#0x10]\n\t" //set GPIOC->BSRR = Pin_8

"ldr r0,=500\n\t" //set Delay argument, time = 500ms
"bl Delay\n\t" //call function Delay

"ldr r2,=0x100\n\t" //load Pin_8
"str r2,[r1,#0x14]\n\t" //set GPIOC->BRR = Pin_8

"ldr r0,=500\n\t" //set Delay argument, time = 500ms
"bl Delay\n\t" //call function Delay

"bl ledloop\n\t" //goto to label ledloop and never return
:::"r0", "r1","r2", "cc", "memory");

}
inline int addition(int val1, int val2)
{
int temp;
__ASM volatile(
"add %[result],%[val1],%[val2]\n\t" //result = val1+val3
"mov r2,#100\n\t" //set loop count = 100
"loopi1:\n\t"
"add %[result],%[result],#1\n\t" //result = result+1
"subs r2,r2,#1\n\t" //decrement loopcoount
"bne loopi1\n\t" //if not zero then keep looping


:[result]"=r" (temp)
:[val1]"r" (val1), [val2]"r" (val2)
: "r2", "cc"
);
return temp;
}
/**
**===========================================================================
**
** Abstract: main program
**
**===========================================================================
*/
int main(void)
{

int newval=0;
/* GPIOC clock enable */
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

newval = addition(1,5);

/* Enable green led PC9 and blue led PC8 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOC, &GPIO_InitStructure);

if (SysTick_Config(SystemCoreClock / 1000))
{
/* Capture error */
while (1);
}

ledLoop();
/* Infinite loop */

while (1)
{

}


}

#ifdef USE_FULL_ASSERT

/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

/* Infinite loop */
while (1)
{
}
}
#endif

/*
* Minimal __assert_func used by the assert() macro
* */
void __assert_func(const char *file, int line, const char *func, const char *failedexpr)
{
while(1)
{}
}

/*
* Minimal __assert() uses __assert__func()
* */
void __assert(const char *file, int line, const char *failedexpr)
{
__assert_func (file, line, NULL, failedexpr);
}

Tidak ada komentar:

Posting Komentar