第一次使用csdn的博客,记录一个小产品的开发过程

来源:互联网 发布:matlab黄金分割算法 编辑:程序博客网 时间:2024/06/07 13:52

    现在时间是2014年4月30日,我在网上订购的usb转串口线和母口对母口的DB9线到了,加上原有的两块奋斗STM32开发板和2.4G无线通信模块,我准备开发一款通过手机进行控制的小灯,同时,小灯上有mini键盘,可以设置一个时间,到了时间等会亮起来,同时向手机推送提醒。

    好了,现在开始准备,下载帝特DT5002usb转串口线的驱动。

    (16:01)

      驱动下载成功,但是发现直通的DB9线没有工作,看来要换交叉线试试。

     (22:53)

    下午从同学那儿借来了23交叉的串口线,试了下,没有问题了,down了个官方例程进去,正常使用。决定采用ucos来实现任务的管理和调度,打开了官方提供的资料中的ucos控制LED例程,粗略浏览了一下。略有点困,回寝室休息。明日继续。



      五月2日休息一天,五月三日继续。


      (11:03)

       查看自己一年前写过的ucos代码,回忆一下。

       

        5月4日

      (21:00)

        昨天回忆了一下STM32芯片开发的大概流程,今天试着在ucos中写入了自己的一个Task,编译运行,没有问题,但是后来发现按键的控制应该采用中断来进行,于是开始写4*4矩阵按键的相关驱动,也就是如下这款:

                       

                                              图1 4*4矩阵按键

    自己写了一个demo程序,按键的反应不是很灵敏,有些按键没有反应,正在调试中。

5月5日

    在网上查阅了一下STM32 gpio口的输入输出模式,结合STM32官方手册,得到如下结论:

STM32中IO模式:
(1) 浮空输入_IN_FLOATING ——浮空输入,可以做KEY识别,RX1
(2)带上拉输入_IPU——IO内部上拉电阻输入
(3)带下拉输入_IPD—— IO内部下拉电阻输入
(4) 模拟输入_AIN ——应用ADC模拟输入,或者低功耗下省电
(5)开漏输出_OUT_OD ——IO输出0接GND,IO输出1,空,需要外接上拉电阻,才能实现输出高电平。当输出为1时,IO口的状态由上拉电阻拉高电平,但由于是开漏输出模式,这样IO口也就可以由外部电路改变为低电平或不变。可以读IO输入电平变化,实现C51的IO双向功能
(6)推挽输出_OUT_PP ——IO输出0-接GND, IO输出1 -接VCC,读输入值是未知的
(7)复用功能的推挽输出_AF_PP ——片内外设功能(I2C的SCL,SDA)
(8)复用功能的开漏输出_AF_OD——片内外设功能(TX1,MOSI,MISO.SCK.SS)

  我采用了四个口推挽输出,四个口下拉输入。发现进入中断不是我设计的情况,我设定的外部中断代码入如下:

//PA4、PA6、PB0、PB11作为中断检测口,检测到终端后即进入LEDsmartcontrol()函数
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource4);  
  
  EXTI_InitStructure.EXTI_Line = EXTI_Line1;   
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  //EXTI中断
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;  //上升沿触发
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;   //使能
  EXTI_Init(&EXTI_InitStructure);

  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource6);  
  
  EXTI_InitStructure.EXTI_Line = EXTI_Line2;   
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  //EXTI中断
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;  //上升沿触发
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;   //使能
  EXTI_Init(&EXTI_InitStructure);

  GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0); 
  
  EXTI_InitStructure.EXTI_Line = EXTI_Line3;   
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  //EXTI中断
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;  //上升沿触发
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;   //使能
  EXTI_Init(&EXTI_InitStructure);

  GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource11);  
  
  EXTI_InitStructure.EXTI_Line = EXTI_Line4;   
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  //EXTI中断
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;  //上升沿触发
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;   //使能
  EXTI_Init(&EXTI_InitStructure);

而进入中断却分别是由A1-A4端口触发的,继续调试之。

查看STM32手册,发现其外部中断是如图2进行设计的,也就是说PA0-PG0被触发都会进入EXIT0中断,于是改变策略,通过进入中断之后来进行键盘扫描。

图2 STM32外部中断IO映像

      

    (2014 05 08 16:23)

今天将键盘驱动写完,测试了下,一切良好,之前遇到的问题在于进入中断之后没有及时清除中断标志位,导致重复进入中断,而且抖动检测也花了点力气。

开始写数据发送端与接收端的通信协议。

   (2014 05 11)

昨天写完了数据发送端和数据接收端的2.4G通信程序,采用的芯片是nrf24l01,由于GPIO口占用的问题,导致数据只能单向传输,反正数据量需求不是很大,先将就用着吧。

今日开始写java的串口通信程序,一开始采用javax.comm,结果不支持64位系统,发现里面代码还是1998年写的!!果断换用RXTX。

(2014 05 19)

上周硕士毕业答辩,搞完后休息了一段时间,今天继续,用RXTX搞定串口的通信,下面直接贴代码:

import java.io.*;
import java.util.*;
import gnu.io.*;


//20140519调试通过


public class NRFToComm implements  SerialPortEventListener {
static CommPortIdentifier portId;
// 枚举类
static Enumeration portList;
SerialPort serialPort;
Thread readThread;
protected BufferedReader comReader;


public static void main(String[] args) {
portList = CommPortIdentifier.getPortIdentifiers();


/*
* 不带参数的getPortIdentifiers方法获得一个枚举对象,该对象又包含了系统中管理每个端口的CommPortIdentifier对象
* 。 注意这里的端口不仅仅是指串口,也包括并口。这个方法还可以带参数。getPortIdentifiers(CommPort)获得与已经被应
* 用程序打开的端口相对应的CommPortIdentifier对象。getPortIdentifier(String
* portName)获取指定端口名(比如“COM3”) 的CommPortIdentifier对象。
*/


while (portList.hasMoreElements()) {
portId = (CommPortIdentifier) portList.nextElement();
/* getPortType方法返回端口类型 */
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
/* 找Windows下的第一个串口 */
if (portId.getName().equals("COM3")) {
System.out.println("com3 is OK");
NRFToComm reader = new NRFToComm();
}
}
}
}


public NRFToComm() {
System.out.println("------------------1");
try {
/*
* open方法打开通讯端口,获得一个CommPort对象。它使程序独占端口。如果端口正被其他应用程序占用,将使用
* CommPortOwnershipListener事件机制
* ,传递一个PORT_OWNERSHIP_REQUESTED事件。每个端口都关联一个
* InputStream和一个OutputStream
* 。如果端口是用open方法打开的,那么任何的getInputStream都将返回
* 相同的数据流对象,除非有close被调用。有两个参数,第一个为应用程序名;第二个参数是在端口打开 时阻塞等待的毫秒数。
*/
serialPort = (SerialPort) portId.open("app", 2000);
System.out.println("------------------2");


} catch (PortInUseException e) {
}
try {
/* 获取端口的输入流对象 */
// inputStream = serialPort.getInputStream();
comReader = new BufferedReader(new InputStreamReader(
serialPort.getInputStream()));
System.out.println("------------------3");


} catch (IOException e) {
}
try {
/* 注册一个SerialPortEventListener事件来监听串口事件 */
serialPort.addEventListener(this);
System.out.println("------------------4");


} catch (TooManyListenersException e) {
}
/* 数据可用 */
serialPort.notifyOnDataAvailable(true);
// 自己添加,20140512
serialPort.notifyOnOutputEmpty(true);
try {
/* 设置串口初始化参数,依次是波特率,数据位,停止位和校验 */
serialPort.setSerialPortParams(115200, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
System.out.println("------------------5");
} catch (UnsupportedCommOperationException e) {
System.out.println("error");
}
// 可以在线程总植入socket通信或者nio通信的部分,目前暂时屏蔽
// readThread = new Thread(this,"test");
// readThread.start();
}


// 串口事件
public void serialEvent(SerialPortEvent event) {
// System.out.println("---------in serialEvent----------");
switch (event.getEventType()) {
case SerialPortEvent.BI:/* Break interrupt,通讯中断 */
// System.out.println("in BI");
// break;
case SerialPortEvent.OE:/* Overrun error,溢位错误 */
case SerialPortEvent.FE:/* Framing error,传帧错误 */
case SerialPortEvent.PE:/* Parity error,校验错误 */
case SerialPortEvent.CD:/* Carrier detect,载波检测 */
case SerialPortEvent.CTS:/* Clear to send,清除发送 */
case SerialPortEvent.DSR:/* Data set ready,数据设备就绪 */
case SerialPortEvent.RI:/* Ring indicator,响铃指示 */
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:/*
* Output buffer is
* empty,输出缓冲区清空
*/
break;
case SerialPortEvent.DATA_AVAILABLE:/*
* Data available at the serial
* port,端口有可用数据。读到缓冲数组,输出到终端
*/
try {
while (comReader.ready()) {
System.out.println("---" + comReader.readLine());
}
System.out.println("-----------------------");
} catch (IOException e) {
}
break;
}
}
}


接下来就是将串口得到的数据进行处理了,准备采用一些设计模式,一边学习一下设计模式,一边写代码。

20140617

毕业了,最后一个月各种毕业旅行,各种毕业聚餐,android客户端还是没有完成,不过系统实现了4*4键盘驱动,基于nrf24l01的2.4G无线通信,用java实现的串口信息读取等功能,以后基于这些技术还是可以做一些别的东西的,直播结束,告一段落,开始新的生活和工作。


0 0
原创粉丝点击