|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
前端时间晒了自己入手的<MPLAB STARTER KIT FOR PIC18 mcuS>,大概了解了一下之后,发现8位单片机并不适合我玩,因为我习惯了32位单片机的高大上(8位机基本没用过,起步就是16位的MSP430),所以后来又入手了<PIC32 Ethernet Starter Kit II>。
/ @* @- ~' ?' |' W! m7 n; x: b8 a. Q6 l# C l/ f& e
说说我选择PIC32的理由(这个纯属个业余爱好,就是玩,不用于任何产品),因为平时较多的时候使用Mac Book,Microchip的MPLAB X开发环境是跨平台的,可以运行在windows、linux以及OS X上,能在OS X上很方便玩起来的单片机绝对不多(虽然有GCC这种跨平台神器,但是大家都知道,新手根本玩不转这东西);另外MPLAB X开发环境以及XC系列编译器是免费的,虽然免费的XC编译器好像很渣的样子(不能选择优化)。
! h/ d3 U1 X f+ C" Z/ F8 F- t' M$ s; F! d7 O+ \( J1 D
PIC32主要包括两大系列,PIC32MX和PIC32MZ,本文主要针对PIC32MX795F512L。PIC32MX7xx采用MIPS32® M4K内核,工作电压2.3V-3.6V,最高主频80MHz。: x2 z) d0 J3 k* b/ G4 S
4 h" a3 k/ U5 q/ X- X
这几天在看一本书《32位单片机C语言编程基于PIC32》,英文名《Programming 32-bit Microcontrollers in C Exploring the PIC32》(下载链接:http://download.eeworld.com.cn/download/lcofjp/62303),在此分享一些心得。
. i5 s5 R z# v7 v* R; ^2 D; FPIC32也拥有像STM32类似的外设库(PIC32MX Peripheral Library),在使用的时候包含plib.h即可。先来说说IO口,PIC32提供两种调试接口,JTAG和ICSP/ICD接口,要使用PORTA的部分引脚作为IO口,必须禁止JTAG接口:DDPCONbits.JTAGEN = 0; PORTB的大部分引脚与ADC输入引脚复用,复位时被配置为模拟功能,若要作为IO口使用,则需配置ADC模块: AD1PCFG = 0xFFFF; 如果某个外围模块的输入输出引脚与IO端口复用,那么一旦启用该外围设备,它就将完全控制该IO端口,与方向控制寄存器(TRISx)的内容无关,然而在8位架构中,即使该模块需要使用这些引脚,用户也得自己制定每个引脚的正确方向。6 w1 i$ C( c2 e6 b; `2 y
@+ {; r0 q) Q9 i9 dPIC32的中断分为两种工作模式:单向量工作模式和多向量工作模式。单向量工作模式只有一个中断函数,所有中断都在同一个函数中得到响应(8位单片机基本都是这种模式),可想而知,如果有多个中断要响应,则要判断多个标志位才能确定是产生了哪个中断,因此这种中断响应的延迟很大。多向量工作模式的话,和ARM cortex-M3的原理差不多,可以每个外设模块使用一个中断向量,最多可达64个中断向量。中断优先级分为两种,组优先级和子优先级,组优先级有0-7共8个,上电时,所有中断源的优先级都被默认地设定为ipl0,并屏蔽所有的中断。在相同的组优先级内,还有两个数据位用于定义4个子优先级。如果有2个组优先级相同的事件发生,那么子优先级高者将先被响应。每款PIC32单片机都定义了各种中断源的默认相对优先级。当其他条件都无效时(组优先级和子优先级都相同),将根据自然顺序决定响应同时发生的多个事件中的哪一个。
7 m$ B" Z) S1 l2 ~0 Q中断函数的写法(其中一种,比较简单的写法): U) c& l7 s- k
void __ISR(VECTOR, IPL) HandlerName(void);
, [' N7 [; Q0 S/ H: a其中VECTOR指定要响应的某个中断向量,IPL指定中断的优先级。9 o5 j4 B- r4 ~
例如:! ~% I; p- a5 U; j5 y5 X
void __ISR(_TIMER_1_VECTOR, IPL0SOFT) Timer1ISR(void)
I+ \6 p; q6 k5 y{9 B0 V* i: I+ _+ G4 a
}+ c! A# V5 C2 ^. b
最后来个流水灯的示例吧,调了半个晚上才弄出来,问题在于要给FPB进行分频时,就不要执行SYSTEMConfigPeRFormance函数了,它会把FPB调到系统能接受的最大值,导致频率不对。. T+ W3 _" \ L; U
# o* M0 E. b3 V/ p# C5 W
#include <stdio.h>
- C! `2 [) L# h5 R5 O8 t, L" J#include <stdlib.h>- O- v* S4 I+ [
#include <stdint.h>% V q/ T9 ~8 k# l& d
#include <plib.h>; ?9 W' }, M: K% E0 f' c
' i8 d% W6 s( ^* N5 Y
// DEVCFG3) P6 X1 r- u( X' v1 b7 O( w
// USERID = No Setting- M+ `" i8 F& t" u% c' b
#pragma config FSRSSEL = PRIORITY_7 // SRS Select (SRS Priority 7)
) A+ o+ X+ y' R, U) ]: y#pragma config FMIIEN = ON // Ethernet RMII/MII Enable (MII Enabled)
/ Z# d' S2 i: s! {6 P- R7 u#pragma config FETHIO = ON // Ethernet I/O Pin Select (Default Ethernet I/O)9 M, S1 j& f5 K$ Q
#pragma config FCANIO = ON // CAN I/O Pin Select (Default CAN I/O)
$ \8 E" y6 o( s! \#pragma config FUSBIDIO = ON // USB USID Selection (Controlled by the USB Module)
. b+ c7 e/ l5 L1 Z, I& `#pragma config FVBUSONIO = ON // USB VBUS ON Selection (Controlled by USB Module)
$ g( m" i8 f4 T+ V+ ^# a9 y4 M% R1 d2 [" U
// DEVCFG2
. l2 E' d' W/ o M" L#pragma config FPLLIDIV = DIV_2 // PLL Input Divider (4x Divider)
& k# r' {% ?# f; m" C#pragma config FPLLMUL = MUL_18 // PLL Multiplier (18x Multiplier)
) o4 O3 P2 } c ?( P2 j6 \: \+ `#pragma config UPLLIDIV = DIV_1 // USB PLL Input Divider (1x Divider)
8 ~3 P: ~3 V% M- S+ j#pragma config UPLLEN = OFF // USB PLL Enable (Disabled and Bypassed)
3 Z8 Y$ Z& `: t( s0 \, A* ]* E0 _#pragma config FPLLODIV = DIV_1 // System PLL Output Clock Divider (PLL Divide by 1)
/ \ V* t: X. v, Q; ^
9 j! |( Q0 r, U9 g// DEVCFG14 c8 ]) k) ~3 B7 a
#pragma config FNOSC = PRIPLL // Oscillator Selection Bits (Primary Osc (XT,HS,EC))+ F$ ?# r* c1 s; h
#pragma config FSOSCEN = ON // Secondary Oscillator Enable (Enabled)
; t6 m2 _1 j; X" o' V1 Y% V+ Z' ^5 o#pragma config IESO = ON // Internal/External Switch Over (Enabled)
& F' G" w0 S. D6 A' K#pragma config POSCMOD = XT // Primary Oscillator Configuration (XT osc mode)) x5 ?8 ~0 F8 `# |" m, q1 ~. S
#pragma config OSCIOFNC = OFF // CLKO Output Signal Active on the OSCO Pin (Disabled)
4 J& J( n$ K/ Q2 E# A" l" u#pragma config FPBDIV = DIV_8 // Peripheral Clock Divisor (Pb_Clk is Sys_Clk/8)
2 _, @3 _+ Z5 B) j, t9 _& u) w# A5 `' j#pragma config FCKSM = CSDCMD // Clock Switching and Monitor Selection (Clock Switch Disable, FSCM Disabled)3 U: ]: s* \5 R8 q
#pragma config WDTPS = PS1048576 // Watchdog Timer Postscaler (1:1048576)
3 w% V7 d8 P6 B" d#pragma config FWDTEN = OFF // Watchdog Timer Enable (WDT Disabled (SWDTEN Bit Controls))
t5 K) D( V& W0 R
+ X' C( p" z3 ` v. ~" E// DEVCFG0
; Q9 W( F: b3 Z9 s$ `& c#pragma config DEBUG = OFF // Background Debugger Enable (Debugger is disabled)# k( h0 N+ f1 h! d. h, q
#pragma config ICESEL = ICS_PGx2 // ICE/ICD Comm Channel Select (ICE EMUC2/EMUD2 pins shared with PGC2/PGD2)
) F3 k+ }! z9 Q2 Z, z- z+ }#pragma config PWP = OFF // Program Flash Write Protect (Disable)& p ^/ p7 ^) Z. {4 I
#pragma config BWP = OFF // Boot Flash Write Protect bit (Protection Disabled)
; C% l6 C7 m9 {5 f% R- U7 a$ ]#pragma config CP = OFF // Code Protect (Protection Disabled)
+ R: r3 x# k& g! k) @: o5 t. \. N- A {3 P
/*) r3 B* @* N& N- l
* KEY1,2,3 === RD6, RD7, RD13
+ b1 |: Q2 c/ d; f6 V* LED1,2,3 === RD0, RD1, RD2
2 _/ k& a" ?! ~& b2 k: C1 x9 v*/
: J* m+ u3 {* Mvolatile uint32_t value = 0;( H1 k4 d5 o3 O' ~5 K) k
' O# v3 E; O9 C7 P( |+ O' C- F) Jint main(int argc, char** argv) {. T. s6 C4 d2 e% Y( u& D9 L
: m1 u4 m* F* B
uint32_t old_value = 0;; F+ x4 V- w/ | Q1 k2 r
//SYSTEMConfigPerformance(72000000L);
4 i6 M6 U4 r& K1 r$ f DDPCONbits.JTAGEN = 0; e5 g% ?) r) [, K! u
TRISDCLR = 7;* ^: ~4 E% x; _- J; ?; O8 }
PR1 = 35155;
3 B3 V" S Y1 y2 }: J T1CON = 0x8030;
' {4 N' \& t I Z' u A8 p4 T, i$ I. }
INTConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR);// INTEnableSystemMultiVectoredInt();8 a- _5 x% _9 W0 c$ {& a0 E
mT1SetIntPriority(1);: V/ M L! P) A7 v5 r8 ]
mT1IntEnable(1);
! ], V8 w8 x Y/ w INTEnableInterrupts();4 }' b% {( }6 S. p
( d Y& G t# L% u while(1)
4 Y+ ~' i- G/ n: I7 T {/ u/ P- h" F2 R0 b A+ u! F
if (old_value != value)
+ }, u/ m3 E1 N: ~4 H5 W: d {
# s/ Y8 ~* O N5 E& l2 K, ]0 @ LATD = value;: E: n/ V6 L7 M. D
old_value = value;
. v2 f% s5 W* o. j# | }
2 t6 c& e4 g7 |9 `4 @" g7 X1 R }
3 }' u: K, p; \: J" Y- { return (EXIT_SUCCESS);. w$ h8 n4 V' I% y
}
8 o4 Z. |. k/ g# l3 M. R& I a" L$ x/ t; ?
void __ISR(_TIMER_1_VECTOR, IPL1SOFT) Timer1ISR(void)
* ~" ` X3 V' x/ ~ U) M{- X9 ]4 T+ i* y$ r( N! a
switch(value): t9 c, ~. f' J+ Q! C+ ^8 j
{' }; M9 n8 d2 ~; L; q
case 1:
# W9 J1 t& F, E( B+ f/ x value = 2;
; _* {9 U( C! ?$ ~3 D% }0 P; |9 m5 B break;
( n5 L r" R7 m8 V, L! ^7 D' z+ f case 2:
9 P( f0 e5 x$ y* _3 a M3 f. t! I1 x value = 4;
- r, F1 d5 y% U2 V) @ break;
7 i0 j1 J u, R4 ^% i case 4:/ ?7 [: j3 S$ \! I) P: o! }* X |
value = 1;
/ Q' X; o. G$ G break;
* @& W( w% k: W1 e- [) N default:
4 G5 G2 k3 V3 M5 i9 p/ C# L7 \ value = 1;% m6 m4 T+ H! T8 p7 x3 w+ G. D
break;/ s# b' F+ ?# C8 y
}
r! z$ n; v* w! z: M ~- g6 s mT1ClearIntFlag();+ Q l6 F" Z# M/ o5 l
}
. J, b) e W" P4 p* `- J3 w复制代码 |
|