
然后是程序设计,
1,设置时钟,关键的有三个地方,敏兄罩
A,在设置系统时钟为72M之后,
[cpp] view plaincopy
RCC_PCLK1Config(RCC_HCLK_Div2)
[cpp] view plain copy
RCC_PCLK1Config(RCC_HCLK_Div2)
设置PCLK1频率为36M
B,
[cpp] view plaincopy
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE)
[cpp] view plain copy
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE)
使能GPIOB总线时钟,即USART3的端口所在的IO;并使能复用时钟。
C,
[cpp] view plaincopy
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE)
[cpp] view plain copy
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE)
使能USART3总线时钟。
2,设置IO,
[cpp] view plaincopy
GPIO_InitTypeDef GPIO_InitStructure
/* Configure USART3 CK(PB.12) as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = SAM0_CLK
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz
GPIO_Init(SAM0_Port, &GPIO_InitStructure)
/* Configure USART3 Tx (PB.10) as alternate function open-drain */
GPIO_InitStructure.GPIO_Pin = SAM0_IO
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD
GPIO_Init(SAM0_Port, &GPIO_InitStructure)
/* Configure Smartcard Reset */
GPIO_InitStructure.GPIO_Pin = SAM0_RST
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP
GPIO_Init(SAM0_Port, &GPIO_InitStructure)
[cpp] view plain copy
GPIO_InitTypeDef GPIO_InitStructure
/* Configure USART3 CK(PB.12) as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = SAM0_CLK
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz
GPIO_Init(SAM0_Port, &GPIO_InitStructure)
/* Configure USART3 Tx (PB.10) as alternate function open-drain */
GPIO_InitStructure.GPIO_Pin = SAM0_IO
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD
GPIO_Init(SAM0_Port, &GPIO_InitStructure)
/* Configure Smartcard Reset */
GPIO_InitStructure.GPIO_Pin = SAM0_RST
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP
GPIO_Init(SAM0_Port, &GPIO_InitStructure)
其中已经定义SAM0_CLK为GPIO_Pin_12,定义SAM0_Port为GPIOB,定义SAM0_RST为GPIO_Pin_11,定义SAM0_IO为GPIO_Pin_10,
3,设置USART3
[cpp] view plaincopy
USART_InitTypeDef USART_InitStructure
USART_ClockInitTypeDef USART_ClockInitStructure
/* USART Clock set to 3.6 MHz (PCLK1 (36 MHZ) / 10) */
USART_SetPrescaler(USART3, 0x05)
/* USART Guard Time set to 16 Bit */
USART_SetGuardTime(USART3, 16)
USART_StructInit(&USART_InitStructure)
USART_InitStructure.USART_BaudRate = 9677
USART_InitStructure.USART_WordLength = USART_WordLength_9b
USART_InitStructure.USART_StopBits = USART_StopBits_1_5
USART_InitStructure.USART_Parity = USART_Parity_Even
USART_Init(USART3, &USART_InitStructure)
USART_ClockInitStructure.USART_Clock = USART_Clock_Enable
USART_ClockInit(USART3, &USART_ClockInitStructure)
/* Enable the USART3 Parity Error Interrupt */
USART_ITConfig(USART3, USART_IT_PE, ENABLE)
/* Enable the USART3 Framing Error Interrupt */
USART_ITConfig(USART3, USART_IT_ERR, ENABLE)
/* Enable USART3 */
USART_Cmd(USART3, ENABLE)
/* Enable the NACK Transmission */
USART_SmartCardNACKCmd(USART3, ENABLE)
/* Enable the Smartcard Interface */
USART_SmartCardCmd(USART3, ENABLE)
[cpp] view plain copy
USART_InitTypeDef USART_InitStructure
USART_ClockInitTypeDef USART_ClockInitStructure
/* USART Clock set to 3.6 MHz (PCLK1 (36 MHZ) / 10) */
USART_SetPrescaler(USART3, 0x05)
/* USART Guard Time set to 16 Bit */
USART_SetGuardTime(USART3, 16)
USART_StructInit(&USART_InitStructure)
USART_InitStructure.USART_BaudRate = 9677
USART_InitStructure.USART_WordLength = USART_WordLength_9b
USART_InitStructure.USART_StopBits = USART_StopBits_1_5
USART_InitStructure.USART_Parity = USART_Parity_Even
USART_Init(USART3, &USART_InitStructure)
USART_ClockInitStructure.USART_Clock = USART_Clock_Enable
USART_ClockInit(USART3, &USART_ClockInitStructure)
/* Enable the USART3 Parity Error Interrupt */
USART_ITConfig(USART3, USART_IT_PE, ENABLE)
/* Enable the USART3 Framing Error Interrupt */
USART_ITConfig(USART3, USART_IT_ERR, ENABLE)
/* Enable USART3 */
USART_Cmd(USART3, ENABLE)
/* Enable the NACK Transmission */
USART_SmartCardNACKCmd(USART3, ENABLE)
/* Enable the Smartcard Interface */
USART_SmartCardCmd(USART3, ENABLE)
主要配置USART3的时钟为3.6M,并且使能时钟,波特率为9677(这个值是参考官方例程的,9600也可以),字节长度为9bits(stm32中文参考资料上介绍smartcard功能时,应该设为8bits,但是设为8bits调试不成功,这个郁闷),停止位设为1.5bits,校验位设为偶校验(奇校验也可以的),其它的使能smartcard功能,都要设置好。
3,编写复位程序,ISO7816中,对IC卡的 *** 作,重要的一步就是获取复位返回信息。
1:C51编译器如何区分位地址和字节地址是靠预定义实现的,比如:sfr P0 = 0x80sbit P0_0 = 0x80前者声明了P0端口地址位于0x80,后者说明了P0端口信胡唤的bit0,即P0.0位于位地址空间0x80处。这滑凯做清2个0x80具有完全不同的含义,靠关键字sfr和sbit来区别。这样当程序被编译时,编译器会依此编译成相应的汇编语言。例如:
C51语句: P0 = 1
P0声明为sfr,因此编译成:mov 80h,01h,将把0x01数据送入0x80单元,由于0x80单元物理上对应P0端口,因此,P0.0脚将输出高电平(其实是呈现高阻态,P0口独有的),其他.1-.7脚输出低电平。
C51语句: P0_0 = 1
P0_0声明为sbit,因此编译成:setb 80h,这将把位地址空间的0x80地址的bit的值置1。这个位正是P0口的bit0,执行后,P0.0将输出高阻态。而P0.1-.7不会变化。
2:C51为什么要嵌套汇编
51单片机一个显著优点就是指令执行时间固定,因此可以适应时序要求严格的场合。例如符合ISO7816协议的cpu卡的读写,对时序要求比较严格。其实就是用io脚做出来的同步半双工串口。支持cpu卡的程序一般比较庞大,需要用c51来组织,但是由于c编译的不确定性,必须把底层程序封装成汇编语言模块嵌入到工程中。这就带来几个问题:如何声明函数、参数如何传递等。限于篇幅,不能说得很细。下面举例:
汇编程序单独保存一个文件,加入到工程中,函数如下:
_proc_a:
mov a, r7
inc a
mov r7, a
ret
用c语言在.h文件中声明: extern unsigned char proc_a(unsigned char val)
调用时形如: retvalue = proc_a(0x11)
说明:
a:汇编程序如果带参数,则需要在汇编程序前多加一个下划线。而声明它的地方不用加(伟福编译器这么要求的)。
b:函数的形参中第一参数用R7传递,函数返回值用R7返回,这是C51的通用规范。其他参数都有相应规定。函数可以返回一个位,用psw的c位返回。c:上面的语句,执行顺序是把0x11给R7,然后跳转子程序,子程序将它加1后送回。
d:函数跳转到汇编程序时,本区的R0-R7,A,B,PSW,DPTR等寄存器可以供子程序使用,不必考虑调用后是否要恢复这些常规资源。上例中,A的值被函数使用了,编程者不必恢复调用前的值。
读SIM卡裤帆岁短信代码实验//SELECT ATR返回之后
A0 A4 00 00 02
3F 00
9F 17
//A0 A4 00 00 02 是命令头,CLA = A0表示GSM应用,INS = A4 表示SELECT,//P1 P2 = 00 00 是参数,P3 = 02是数据的长度(或返回数据的长度)表示( 2 )
//选择文件,选中文件为3F 00 代表MF
//9F 17 是返回状态,表示---成功,有23 个字节的信息等待GET RESPONSE
//SELECT
A0 A4 00 00 02
7F 10
9F 17
//A0 A4 00 00 02 是命令头,CLA = A0表示GSM应用,INS = A4 表示SELECT,//P1 P2 = 00 00 是参数,P3 = 02是数据的长度(或返回数据的长度)表示( 2 )
//选择文件,选中文件为7F 10 代表TELECOM
//9F 17 是返回状态,表示---成功,有23 个字节的信息等待GET RESPONSE
//SELECT
A0 A4 00 00 02
6F 3C
9F 0F
//A0 A4 00 00 02 是命令头,CLA = A0表示GSM应用,INS = A4 表示SELECT,//P1 P2 = 00 00 是参数,P3 = 02是数据的长度(或返回数据的长度)表示( 2 )
//选择文件,选中文件为6F 3C 代表SMS[CDMA-SMS]
//9F 0F 是返回状态,表示---成功,有15 个字节的信息等待GET RESPONSE
//GET RESPONSE
A0 C0 00 00 0F
00 00 0A 50 6F 3C 04 00 11 FF 44 01 02 01 B0
90 00
//A0 C0 00 00 0F 是命令头,CLA = A0表示GSM应用,INS = C0 表示GET RESPONSE,//P1 P2 = 00 00 是参数,P3 = 0F 是数据的长度(或返回数据的长度)表示( 15 )
//轿掘返回数据见上,其中
//--00 00 保留
//--0A 50 占用的空间大小,表示2640字节
//--6F 3C 选中File的ID
//--04 选中文件的类型,01-MF, 02-DF, 04-EF
//--00 见11.11 9.2.1 detail 3
//--11 FF 44 访问权限
//--01 文件状态,见11.11 9.3
//--02 后面数据的长度,表示2
//----01 文件结构,见11.11 9.3
//----B0 记录长度,见11.11 9.2.1 detail 4
//90 00 是返回状态,表示---成功
//READ RECORD
A0 B2 01 04 B0
01 08 91 68 31 08 10 00 05 F0 00 05 A1 01 80 F6 00 08 70 21 21 61 63 14 23 86 00 28 00 31 00 2F 00 32 00 29 5C 0A 65 6C 76 84 5B A2 62 37 FF 0C 60 A8 5D F2 5F 00 90 1A 75 45 54 2C 65 E0 5F E7 8B A1 52 12 FF 0C 8B E5 4E 1A 52 A1 4E 8E 4E 0B 67 08 75 1F 65 48 30 02 67 08 4F 7F 75 28 8D 39 00 31 00 30 51 43 FF 0C 53 05 54 2B 67 2C 57 30 88 AB 53 EB 51 4D 8D 39 30 01 67 65 75 35 66 3E 79 3A 30 01 5F 69 94 C3 30 01 00 32 00 30 52 06 94 9F 67 2C 57 30 4E 3B 53 EB 65 F6 95 7F FF 0C FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
90 00
//A0 B2 01 04 B0 是命令头,CLA = A0表示GSM应用,INS = B2 表示READ RECORD,//P1 P2 = 01 04 是参数,P3 = B0 是数据的长度(或返回数据的长度)表示( 176 )
//读记录,P2 = 04 表示绝对记录号,P1 = 01 为记录号,表示第1 条记录P3 = B0 表示后
//面的数据长度为176
//--收到的短信,已胡睁读
//----08 91 68 31 08 10 00 05 F0 是短信中心号码,表示+8613800100500
//--------------------TON-NPI------------开始
//----91 TON-NPI( 1 0 0 1 0 0 0 1 ),表示
//------bit7为 1
//------bit6, bit5, bit4是TON(type-of-number),值为 0 0 1 ,表示International number
//------bit3-bit0为NPI(numbering-plan-identification),只有当TON为//000, 001, 010的时候NPI才有值,其他应该为0000,值为 0 0 0 1 ,表示//ISDN/telephone numbering plan
//--------------------TON-NPI------------结束
//----01 是SMS-DELIEVE type,( 0 0 0 0 0 0 0 1 ),表示
//--------------------SMS-DELIVER-TYPE------------开始
//------bit1, bit0是 TP-MTI,值为 0 0 ,表示//SMS-DELIVER type( SC to MS direction).
//------bit2是 TP-MMS,值为 0 表示//More messages are waiting for the MS in the SC
//------bit4, bit3 不清楚,值为 0 0
//------bit5是 TP-SRI,值为 0 表示//A status report will be returned to the SME.
//------bit6是 TP-UDHI,值为 0 表示//The TP-UD field contains only the short message.
//------bit7是 TP-RP,值为 0 表示//TS-Reply-Path parameter is not set in this deliver.
//--------------------SMS-DELIVER-TYPE------------结束
//----05 A1 01 80 F6 是TP-OA,表示10086
//--------------------TON-NPI------------开始
//----A1 TON-NPI( 1 0 1 0 0 0 0 1 ),表示
//------bit7为 1
//------bit6, bit5, bit4是TON(type-of-number),值为 0 1 0 ,表示//National number
//------bit3-bit0为NPI(numbering-plan-identification),只有当TON为//000, 001, 010的时//候NPI才有值,其他应该为0000,值为 0 0 0 1 ,表示//ISDN/telephone numbering plan
//--------------------TON-NPI------------结束
//----00 TP-PID
//--------------------TP-PID------------开始
//------bit7, bit6为 0 0
//------bit5-bi50为 0 0 0 0 0 0 表示Short message type 0
//--------------------TP-PID------------结束
//----08 是TP-DCS(00表示压缩英文,04表示未压缩文字,08表示UCS2),
//----70 21 21 61 63 14 23 是TP-SCTS,表示07年12月12日16时36分41秒32时区
//----86 是TP-UDL,表示10进制( 134 ),
//----00 28 00 31 00 2F 00 32 00 29 5C 0A 65 6C 76 84 5B A2 62 37 FF 0C 60 A8 5D F2 //5F 00 90 1A 75 45 54 2C 65 E0 5F E7 8B A1 52 12 FF 0C 8B E5 4E 1A 52 A1 4E 8E 4///E 0B 67 08 75 1F 65 48 30 02 67 08 4F 7F 75 28 8D 39 00 31 00 30 51 43 FF 0C 53 05 //54 2B 67 2C 57 30 88 AB 53 EB 51 4D 8D 39 30 01 67 65 75 35 66 3E 79 3A 30 01 5F //69 94 C3 30 01 00 32 00 30 52 06 94 9F 67 2C 57 30 4E 3B 53 EB 65 F6 95 7F FF 0C //表示"(1/2)尊敬的客户,您已开通畅听无忧计划,该业务于下月生效。月使用费10元,包//含本地被叫免费、来电显示、彩铃、20分钟本地主叫时长,"
//90 00 是返回状态,表示---成功
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)