|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
前端时间晒了自己入手的<MPLAB STARTER KIT FOR PIC18 mcuS>,大概了解了一下之后,发现8位单片机并不适合我玩,因为我习惯了32位单片机的高大上(8位机基本没用过,起步就是16位的MSP430),所以后来又入手了<PIC32 Ethernet Starter Kit II>。
3 v; d* f- Z6 T% l5 T D
* {2 T! I; [. P; ^说说我选择PIC32的理由(这个纯属个业余爱好,就是玩,不用于任何产品),因为平时较多的时候使用Mac Book,Microchip的MPLAB X开发环境是跨平台的,可以运行在windows、linux以及OS X上,能在OS X上很方便玩起来的单片机绝对不多(虽然有GCC这种跨平台神器,但是大家都知道,新手根本玩不转这东西);另外MPLAB X开发环境以及XC系列编译器是免费的,虽然免费的XC编译器好像很渣的样子(不能选择优化)。
% ]; ?3 R' D. i7 L# Y
, u2 |; i6 P: D4 Z, k2 SPIC32主要包括两大系列,PIC32MX和PIC32MZ,本文主要针对PIC32MX795F512L。PIC32MX7xx采用MIPS32® M4K内核,工作电压2.3V-3.6V,最高主频80MHz。
2 ~1 R2 P; f7 n$ K
; z& B) l2 E# q* v: p4 e这几天在看一本书《32位单片机C语言编程基于PIC32》,英文名《Programming 32-bit Microcontrollers in C Exploring the PIC32》(下载链接:http://download.eeworld.com.cn/download/lcofjp/62303),在此分享一些心得。 R- ?' x8 e m
PIC32也拥有像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位架构中,即使该模块需要使用这些引脚,用户也得自己制定每个引脚的正确方向。' X& A5 E, s! g3 z2 \! A! j
6 W6 W2 {% k+ Y# o" Y& T2 EPIC32的中断分为两种工作模式:单向量工作模式和多向量工作模式。单向量工作模式只有一个中断函数,所有中断都在同一个函数中得到响应(8位单片机基本都是这种模式),可想而知,如果有多个中断要响应,则要判断多个标志位才能确定是产生了哪个中断,因此这种中断响应的延迟很大。多向量工作模式的话,和ARM cortex-M3的原理差不多,可以每个外设模块使用一个中断向量,最多可达64个中断向量。中断优先级分为两种,组优先级和子优先级,组优先级有0-7共8个,上电时,所有中断源的优先级都被默认地设定为ipl0,并屏蔽所有的中断。在相同的组优先级内,还有两个数据位用于定义4个子优先级。如果有2个组优先级相同的事件发生,那么子优先级高者将先被响应。每款PIC32单片机都定义了各种中断源的默认相对优先级。当其他条件都无效时(组优先级和子优先级都相同),将根据自然顺序决定响应同时发生的多个事件中的哪一个。9 h6 u: R$ [( G1 z$ {( g% i
中断函数的写法(其中一种,比较简单的写法):
3 t" S4 j+ G* q8 |void __ISR(VECTOR, IPL) HandlerName(void);4 n% b+ r4 ?+ ^. u* t1 O
其中VECTOR指定要响应的某个中断向量,IPL指定中断的优先级。# K# O% t+ B# g4 a3 P, O4 L& B" t4 j
例如:
& O/ D+ x$ Q! G8 ovoid __ISR(_TIMER_1_VECTOR, IPL0SOFT) Timer1ISR(void)( A7 f: K E+ D
{8 G8 M U7 `" M0 [- N3 N" i
}6 R& c+ n6 H' H- H
最后来个流水灯的示例吧,调了半个晚上才弄出来,问题在于要给FPB进行分频时,就不要执行SYSTEMConfigPeRFormance函数了,它会把FPB调到系统能接受的最大值,导致频率不对。' J5 y4 o& q+ b$ f/ Z3 _
+ _1 J! l& {1 F" x. s$ v: u* w#include <stdio.h> N3 |& v6 {: u) N5 l/ R7 I+ t1 y. \
#include <stdlib.h>% a/ I& D1 H$ t0 d/ e
#include <stdint.h>
! v" w5 y! h- i& e5 Z! o9 V: q#include <plib.h>
* G. O* T: d- y1 c) @* _4 D. q. C3 E) H+ F
// DEVCFG3; U4 x7 ~; v. |
// USERID = No Setting/ D) w/ N: V! {4 j7 ?7 Y# U ^
#pragma config FSRSSEL = PRIORITY_7 // SRS Select (SRS Priority 7), S3 c8 G$ A! ?: x4 O2 `/ c
#pragma config FMIIEN = ON // Ethernet RMII/MII Enable (MII Enabled)7 x' {- {7 O% C5 ^' J* N3 k
#pragma config FETHIO = ON // Ethernet I/O Pin Select (Default Ethernet I/O) G: y7 u3 g3 m
#pragma config FCANIO = ON // CAN I/O Pin Select (Default CAN I/O); |0 @7 [+ a. f: n& F) }' v) u
#pragma config FUSBIDIO = ON // USB USID Selection (Controlled by the USB Module)2 O/ o% s+ _1 f3 {2 a7 S( G
#pragma config FVBUSONIO = ON // USB VBUS ON Selection (Controlled by USB Module)
5 ~; F+ e0 a3 p7 h( M- J+ e% [0 K" j6 m+ Q, G
// DEVCFG2# v- K" `5 y; Z: r5 J
#pragma config FPLLIDIV = DIV_2 // PLL Input Divider (4x Divider)1 m) B$ O* V- S
#pragma config FPLLMUL = MUL_18 // PLL Multiplier (18x Multiplier)8 I4 X# S3 Z3 A c: _6 d& }
#pragma config UPLLIDIV = DIV_1 // USB PLL Input Divider (1x Divider)
: ~* g4 {2 I |. s/ |* ?#pragma config UPLLEN = OFF // USB PLL Enable (Disabled and Bypassed)
+ t/ T5 z& ^' l# E6 @#pragma config FPLLODIV = DIV_1 // System PLL Output Clock Divider (PLL Divide by 1)" [! h5 m) ~9 L/ I: W5 d; I
3 [8 }0 p. L0 n! Q/ T( N9 ?
// DEVCFG1
~3 O( L4 J6 j: S9 [6 }#pragma config FNOSC = PRIPLL // Oscillator Selection Bits (Primary Osc (XT,HS,EC))
# p+ M! I3 T* x0 f6 u X6 E#pragma config FSOSCEN = ON // Secondary Oscillator Enable (Enabled)7 {: l9 b& _3 c8 G: ^( j2 J7 c
#pragma config IESO = ON // Internal/External Switch Over (Enabled)0 e7 ?! T8 q! G+ Z1 v
#pragma config POSCMOD = XT // Primary Oscillator Configuration (XT osc mode)
0 r- E$ G9 m; I1 W#pragma config OSCIOFNC = OFF // CLKO Output Signal Active on the OSCO Pin (Disabled)9 k! ` a' P7 p" z5 i6 x3 t
#pragma config FPBDIV = DIV_8 // Peripheral Clock Divisor (Pb_Clk is Sys_Clk/8)
: O* ^0 E8 G& G4 R#pragma config FCKSM = CSDCMD // Clock Switching and Monitor Selection (Clock Switch Disable, FSCM Disabled)2 ]. P* Q# x4 Q9 u/ Y, _" `
#pragma config WDTPS = PS1048576 // Watchdog Timer Postscaler (1:1048576)+ |! E1 a( M7 N6 D, _( T
#pragma config FWDTEN = OFF // Watchdog Timer Enable (WDT Disabled (SWDTEN Bit Controls))
) z& L/ ]7 l2 l |
* ^( x$ I) `! P% E4 ?+ P// DEVCFG0" X! F* {9 q& M v2 u; @" K6 M. G
#pragma config DEBUG = OFF // Background Debugger Enable (Debugger is disabled)
3 h3 A6 `9 q, H: C; G) S8 d#pragma config ICESEL = ICS_PGx2 // ICE/ICD Comm Channel Select (ICE EMUC2/EMUD2 pins shared with PGC2/PGD2)1 O( A& C, C$ L: `8 ^
#pragma config PWP = OFF // Program Flash Write Protect (Disable)
`# h/ e& v$ z3 {/ _* P#pragma config BWP = OFF // Boot Flash Write Protect bit (Protection Disabled)6 w2 ?7 l9 w8 ~0 y0 a: H
#pragma config CP = OFF // Code Protect (Protection Disabled) _! G3 t. T d; m: n9 |
- E8 W7 a( a. W, {' G! R$ q/ B
/*# |. F0 V% }6 h: E; o2 X( g9 T7 n: p6 M6 H
* KEY1,2,3 === RD6, RD7, RD13: a* A. b ]6 ~9 m7 \
* LED1,2,3 === RD0, RD1, RD2
% M" `# W0 P0 q8 t*/
" `. O8 \& G. X5 B3 Svolatile uint32_t value = 0;
5 z3 [7 o3 |+ b* G8 @1 Z
+ B: z' R. }6 R# y% f h* Z/ Vint main(int argc, char** argv) {6 l1 W) F8 \/ P( T' M
' t; ^. z. \1 n% k' k, U: x
uint32_t old_value = 0;
+ c: o- M; \0 \7 W6 G5 C3 O //SYSTEMConfigPerformance(72000000L);
. k! c' Z6 |( s' e' E DDPCONbits.JTAGEN = 0;
- j0 ?! H) P" b5 x TRISDCLR = 7;
( b$ s- [1 |" y. i8 d PR1 = 35155;
' U8 Z/ U* ]% b T1CON = 0x8030;
% R& p# l- [) \6 o9 i. ]6 r5 E" y5 h' n, @* F9 }+ [( @
INTConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR);// INTEnableSystemMultiVectoredInt();
$ x7 P$ H+ `: h. U5 P) h/ r mT1SetIntPriority(1);5 ~; c# k$ `3 V$ F
mT1IntEnable(1);. S1 @5 [+ T4 Z$ `3 Q; y4 d# h
INTEnableInterrupts();6 I& m+ y" \% G$ o! {7 u; O
8 v X9 X' z) _2 z while(1), i: r& N H5 F0 v. N- X
{
{0 C5 x- r- g, M if (old_value != value)
, u) P6 T' X% u( S6 r {
* t" H/ k# E! j LATD = value;
) g3 X4 M6 i( |- T' B6 f old_value = value;$ H$ V6 V x* f+ y; i4 y$ R% s
} I7 v2 m2 U3 w) c9 x/ o2 A
}
) f4 _# c% ~6 Y1 `; r, S return (EXIT_SUCCESS);, H% `5 i1 L9 s4 H
}
* ?7 p; W8 x. a7 p) ~. Y( y4 E& R# c5 d& }: g
void __ISR(_TIMER_1_VECTOR, IPL1SOFT) Timer1ISR(void)2 y% k e: A8 @3 s5 F
{+ Y; E. u3 x8 Q7 j8 E' U
switch(value)
9 c) t3 d* l$ ~9 f {
3 N6 H/ c: C+ q9 D/ X/ {# o case 1:! y e8 s) N1 H, b
value = 2;
( _8 B+ n7 n( V! t. m) N break;
4 i- g& B [- s4 g8 g' p0 z case 2:8 v. t' ^. Z$ ^
value = 4;
: s$ M. l" y+ d8 d" S: P+ v break;
/ n, ]! m( r% N. h) z, d0 a! K case 4:
: A9 D4 Y) g I value = 1;6 l. v5 V% n" }& S W
break;- F$ O7 w3 C( e8 V% W8 X) N1 r1 C
default:
" R4 D" S Q! `% |# b# J7 m value = 1;
! w0 B5 a8 q8 H. L break;
3 [4 _2 V9 X# v6 `4 i& s- e& O }2 D5 d/ h1 ~9 H
mT1ClearIntFlag();! R. S% ~1 o6 {1 Q2 l
}
: k0 r' n) S8 m* N" x4 S6 W复制代码 |
|