【楼主位】 sanhope 积分:42 派别: 等级:------ 来自:
|
第一节: 陌生的她和大叔 人近中年,不知不觉竟然成为孩子的父亲,不知不觉竟然成为别人的大叔,心中很是彷徨,我已不再年少。前些日子学习stm8,一口气工作近2个星期,当时精神饱满,心中很是得意,原来我也可以年轻。谁知放假去了次青岛和家人度假回来后竟然感冒了一个星期,哎,我还是老了。 写完stm8调试记后,就想践踏一下stm32,就像大叔和美女。。。因为只有美女才能让大叔觉得年轻,只有美女才能让大叔精力旺盛,stm32是我的美女吗?我不知道,我要接近她,我要驾驭她。 KEIL 的大名人尽皆知,51年代就大放异彩。说到这儿,不得不说一下那些为电子公益事业做出贡献的先行者们。甚是怀念那个年代,丁丁,老万,所长,午夜听风,龙啸九天等诸多大虾。他们推广keil,他们无私的奉献,就像现在的老key一样,知无不言,言无不尽。 我使用的环境: keil mdk 350 St 的 三合一板 板子虽小,还是可以做很多事情的,白菜老弟做的板子据说很强势,已经预定,现在先解下渴,玩玩只有一个STM32F103C8T6的小家碧玉。 Mdk350集成了st的st link,所以只要在OPTION FOR TARGET 的 DEBUG 和UTILITIES下选择st link debug就可以正确连接。库使用的是v2.01
我要让她跑起来,我需要做什么?
我要有一个时钟,目标是48mhz,这是为了以后调试usb
STM32的时钟和STM8的时钟基本上是一样的。她内部有个8mhz的振荡器,不过我不打算用它。三合一板外部焊接了一个8mhz的晶振我要用她做时钟源。 时钟初始化:
RCC_DeInit(); //恢复默认值这没什么用,不写他也不影响运行
RCC_HSEConfig(RCC_HSE_ON ); //启动外部时钟
while(!RCC_GetFlagStatus(RCC_FLAG_HSERDY));//等待外部时钟稳定
FLASH_SetLatency(FLASH_Latency_1); //48mhz运行时,flash要加一个等待周期 其实刚开始时我没有加这个延时,也没有什么不良的反应,不知道时间长了会不会有问题
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//预缓冲使能
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_6);//pll输出是外部时钟的6倍
RCC_PLLCmd(ENABLE); //使能pll
while(!RCC_GetFlagStatus(RCC_FLAG_PLLRDY));//等待pll稳定
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//切换到PLL时钟
while(RCC_GetSYSCLKSource()!=0x8);//等待系统时钟稳定 RCC_PCLK1Config(RCC_HCLK_Div2);//低速时钟为24mhz
RCC_PCLK2Config(RCC_HCLK_Div1);//高速时钟为48mhz
经过上面的设置,时钟正是工作,我们可以通过这个函数RCC_GetClocksFreq(); 来验证 RCC_ClocksTypeDef RCC_Clocks_T; RCC_GetClocksFreq( &RCC_Clocks_T); RCC_Clocks_T中反应了sys clk, HCLK PCLK1,PCLK2, ADC CLK的频率。
时钟有了,我们还要干点什么?板上有她唯一的外设,led小灯。我要让处于pb5的led亮。 //首先开启PB口的时钟,pb口在高速apb2上 RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB,ENABLE ); 下面要进行pb口的初始化
GPIO_InitTypeDef GPIOB_STR; //定义一个结构变量用于初始化 GPIOB_STR.GPIO_Pin = GPIO_Pin_5; //选择pb5
GPIOB_STR.GPIO_Speed = GPIO_Speed_10MHz; //最大10mhz输出
GPIOB_STR.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
GPIO_Init( GPIOB,&GPIOB_STR); //配置pb5 Pb5已经配置好了,下面我要点亮led,pb5要输出1 GPIO_SetBits( GPIOB,GPIO_Pin_5); 相反熄灭她如下: GPIO_ResetBits( GPIOB,GPIO_Pin_5); 这一节就到这,意法的库真是好东西,stm8调试的时候没有使用是因为实在不愿看那么多的代码。现在学习stm32,顺便把她的库看了看,觉得虽然庞大琐碎,但结构很优美,便用了起来。不过我怕用习惯了,把我自己用傻了,以后换别的cpu时,不会用了。
第二节 定时,中断,和意法的风骚 玩cpu吗当然等玩定时器,重要性在stm8一文中已有描述,这里不再多说。 我要使用tim2实现1s定时,这有些长不够实用,但是我只是玩玩。 第一步要配置时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2|RCC_APB1Periph_SPI2,ENABLE);
Tim2处于时钟树的apb1上。 下面是初始化代码 TIM2->PSC |=24000; //设置预分频,实现1ms
TIM2->ARR = 1000; //1s产生一次中断
TIM2->DIER |=0X1; //允许tim2更新中断
NVIC->ISER[0] |= (u32)(1<<TIM2_IRQChannel); //开tim2中断
TIM2->CR1 |=0X1;//启动tim2 说到这,不能不说意法的风骚,刚开始时翻遍手册也没看到nvic部分的说明,所以第一版本的tim2初始化没有nvic部分,以至不能进tim2的更新中断,后查阅阿莫的论坛才知有c_m3权威指南一物,实在让人无语。这是意法的风骚,这是新手的灾难。 每次新建工程时,keil会自动生成一个文件stm32f10x.s,在里面有中断向量表的描述。将相应的中断函数名实例化,就能实现中断入口。 我的tim2中断函数 void TIM2_IRQHandler(void)//这个函数名能在stm32f10x.s中找到 { static u8 flag; if( flag ) { GPIO_SetBits( GPIOB,GPIO_Pin_5); //下面能实现上文说的led以0.5hz闪烁
flag = FALSE;
} else { GPIO_ResetBits( GPIOB,GPIO_Pin_5);
flag = TRUE; }
TIM2->SR &=0XFFFE; //清楚更新标志
}
上面没有用库函数,是因为我想自己的头脑里脉络更清楚,更复合我自己的风格。其实用库会简单
第三节 SPI和懒懒的我 调试stm8时没有调spi实在是因为没有接口,在加上我这人懒散最终没有调它,如果是美女,我就不会这么客气了吧。 最近身体欠佳,总感觉力不从心。又觉得时间匆匆,再不加把力气真要荒废此生,便生出无奈。 闲话少说,说说spi吧。三合一板只有一个cpu,但它却有两个spi,我用飞线将他们互联,便形成了一个完整的spi通讯接口。 Spi2处于时钟树的apb1,spi1处于时钟树的apb2,时钟部分已将apb1配置为24mhz Apb2为48mhz 首先开启spi2和spi1时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2\ |RCC_APB1Periph_SPI2, \\这个是spi2的选项 ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB\ |RCC_APB2Periph_SPI1\ //这个是spi1的选项 |RCC_APB2Periph_GPIOA\ |RCC_APB2Periph_USART1,ENABLE
); 下面是spi的初始化 u32 x; u8 y;
SPI_InitTypeDef SPI_X;
SPI_X.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //全双工
SPI_X.SPI_Mode = SPI_Mode_Slave;//式
SPI_X.SPI_DataSize = SPI_DataSize_8b;//
SPI_X.SPI_CPOL = SPI_CPOL_High;//时钟空闲是为高
SPI_X.SPI_CPHA = SPI_CPHA_2Edge;//
SPI_X.SPI_NSS = SPI_NSS_Soft;//软件控制
SPI_X.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
SPI_X.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_Init(SPI2,&SPI_X);
SPI2->CR2 |= (1<<SPI_FLAG_RXENIE)|(1<<SPI_FLAG_TXENIE);//接受和发送 中断
NVIC->ISER[1] |= 0X10;//开spi2中断
SPI_X.SPI_Mode = SPI_Mode_Master;
SPI_Init(SPI1,&SPI_X); //spi1为主
SPI1->CR2 |= (1<<SPI_FLAG_RXENIE)|(1<<SPI_FLAG_TXENIE);
NVIC->ISER[1] |= 0X8;
SPI_Cmd(SPI2,ENABLE);
SPI_Cmd(SPI1,ENABLE);//使能spi1和spi2
SPI2->DR = 0Xaa;//发送数据
中断处理函数 void SPI1_IRQHandler( void ) { u16 x; if( SPI1->SR &0X1) { x = SPI1->DR;
}
if( SPI1->SR&0x2 ) { SPI1->DR =++test_data1;
}
}
void SPI2_IRQHandler( void ) { vu16 x; if( SPI2->SR &0X1) { x = SPI2->DR;
if( sam_data < SIZE_BUF ) {
sam_data1[ sam_data++ ] =x;
} else { sam_data = 0; } }
if( SPI2->SR&0x2 ) { SPI2->DR =++test_data; /* if(test_data1!=0) { test_data1 --; } else { test_data1 =10; } */ }
}
外设使用的时候一定要先配置好io的使用模式。我就因为没有配置而吃了大亏。刚开始时收发怎么也不正常,后设置了io的方式才能工作。这大概是对新的事物还不熟悉。 Io的模式无非是,出的数据流设成输出,入的数据流设成输入,什么可说。
关于spi的代码,不是好的风格,其中库夹杂着自己的方法,如果在严格的风格上这不叫方法,叫发疯。 第四节:串口和新凤霞 最近听新凤霞的花为媒,让我有绕梁三日的感觉。喜欢的朋友可以听一下。老艺术家的东西越来越少了。时代在进步,我们在放弃。但放弃的都是优良的传统,如清廉,孝道,公正。 我手里有两个自己做的ch341转串口线缆,将小板的pa9(u1_TX,设置成推挽输出),和pa10(U1_RX,上拉输入) 和ch341相连,就完成了硬件配置。 我要实现的功能,当cpu收到计算机发来的0XAA时,发送8个0X55,在上电时cpu主动发送一次8个0X55.
首先配置时钟, RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB\ |RCC_APB2Periph_SPI1\ //这个是spi1的选项 |RCC_APB2Periph_GPIOA\ |RCC_APB2Periph_USART1,ENABLE //这个是串口项
); 下面是初始化: USART_InitTypeDef uart_x;
NVIC_InitTypeDef nvic_x;
USART_Cmd(USART1,ENABLE); //使能串口
uart_x.USART_BaudRate = 19200;//19200, 8, n ,1
uart_x.USART_WordLength = USART_WordLength_8b;
uart_x.USART_StopBits = USART_StopBits_1;
uart_x.USART_Parity = USART_Parity_No;
uart_x.USART_Mode = USART_Mode_Rx |USART_Mode_Tx;//发送和接受
uart_x.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART1,&uart_x);
USART_ITConfig(USART1,USART_IT_TC,ENABLE);//使能发送完成中断
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//使能接受满中断
nvic_x.NVIC_IRQChannel = USART1_IRQChannel;//nvic的库开启方法
nvic_x.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvic_x);
中断函数 void USART1_IRQHandler( void ) { vu16 x; vu16 y ;
y = USART1->SR;//读状态 if(y & 0X20)//如果是非空中断 { x = USART1->DR&(u16)0xff; // USART_SendData(USART1,0X55);
if( x == 0xaa ) { lentch_x = 0;
USART1->CR1 |=(u16)0X8;//启动一次发送
}
} if(y & 0X40)//发送完成中断 {
if(lentch_x < 8 ) {
USART1->DR = 0X55;
lentch_x++;
} else { USART1->CR1 &=(u16)0XFFF7;; //清楚标志
}
}
}
这次完全使用了库,哈。过两天使用dma试试,接下来还有adc等没有测试,可板子太小了可发挥的余地不多,就剩usb了,可是它太不好肯,得好好的准备准备,过阵子白菜的板子到了在研究。
|
|
2009-06-11,11:24:57 |
|
【1楼】 sunsky 积分:176 派别: 等级:------ 来自:
|
非常精彩。 |
|
2009-06-11,12:23:11 |
|
【2楼】 lollipop 天堂里没有猪头猪脑
 积分:604 派别: 等级:------ 来自:上海
|
有意思 |
|
2009-06-11,12:57:30 |
|
【3楼】 kakaarm 积分:144 派别: 等级:------ 来自:ARM新品:路虎LPC1768开发板(Cortex-M3),板载USB仿真器!JLINK On Board
|
大叔大有文采啦,你不搞文学那是文学界的一大损失啊呵呵 |
|
2009-06-11,15:14:52 |
|
【4楼】 zx5111030 积分:178 派别: 等级:------ 来自:北京
|
mark |
|
2009-06-11,16:47:51 |
|
【5楼】 lihq97 积分:47 派别: 等级:------ 来自:广东江门市新会区
|
很精彩,对我们新手很有帮助! |
|
2009-06-14,09:17:54 |
|
【6楼】 qfmcu 清风徐徐
 积分:216 派别: 等级:------ 来自:济南
|
非常精彩,有续集否? |
|