- //******************************************************************************
- #include "msp430x14x.h" // Standard Equations
- typedef unsigned char uchar ;
- typedef unsigned int uint ;
- /*******************************************
- functional module
- *******************************************/
- void delay_l(int q);
- void ClockInit() ; //时钟初始化
- void UartInit() ; //串口通信初始化函数
- void SendDataToPC(uchar *value) ; //发送数据函数
- void SendDataToPC1(uchar value) ;
- void ADDataTodecimal(uchar *p,uint value) ; //十六进制转换十进制函数
- uchar value[5] ; //用来存放把一个十六进制熟转换为十
- uint temp = 0 ; //Function as exchange data
- uchar i,j ;
- /********************************************
- main function
- ********************************************/
- void main(void)
- {
- WDTCTL = WDTPW+WDTHOLD; // Stop watchdog timer
- value[4] = '/0' ; // ADD A END SIGN TO
- ClockInit();
- UartInit(); //Initial series communication
- P6SEL |= 0x10 ; // Enable A/D channel A3
- ADC12CTL0 = ADC12ON |REFON |REF2_5V ; // Turn on ADC12, set sampling time
- ADC12CTL1 = SHS_1 + SHP + CONSEQ_2 ; // Use sampling timer, set mode
- ADC12MCTL0 |= INCH_4 ; //Select input signal from A0 channel
- delay_l(6) ;
- ADC12CTL0 |= ENC ; // Enable conversions
- CCTL0 = CCIE ; //Enable timerA Interrupt
- TACCR0 = 4000; //Sample frequence about 1000Hz
- TACCR1 = 2000 ;
- TACCTL1 = OUTMOD_3 ; //PWM set/reset
- TACTL = TASSEL_2 + MC_1 + TACLR ; //Use increase count mode
- //TACTL = TASSEL_2 + MC_1 ;
- _BIS_SR(LPM0_bits + GIE) ; // Enter LPM0 LOW-POWER0 MODE
- }
- /********************************************
- //Intialized the SMCLK Clock
- *********************************************/
- void ClockInit()
- {
- BCSCTL1 &=~ XT2OFF ;
- do
- {
- IFG1 &=~ OFIFG ;
- for(uint i=0xff;i>0;i--) ;
- }
- while((IFG1 & OFIFG));
- BCSCTL1 |= SELS | DIVS1 | DIVS0 ;
- }
- /*******************************************
- USART初始化,选择波特率为9600,8位,无校验位
- *******************************************/
- void UartInit()
- {
- P3SEL |= 0x30 ; // P3.4,5 = USART0 TXD/RXD
- ME1 |= URXE0 + UTXE0 ; // Enable USART0 T/RXD
- UCTL0 |= CHAR ; // 8-bit character
- UTCTL0 |= SSEL0 ; // UCLK = ACLK
- //**Common used baud rates********************/
- // UCLK---------Clock----------32k---------ACLK
- // UxBR1=0x0,UxBR0=0x1B,UxMCTL=0x03---1200bit/s
- UBR10 = 0x00 ; //SET BAUD // UxBR1=0x0,UxBR0=0x0D,UxMCTL=0x6B---2400bit/s
- UBR00 = 0x06 ; // UxBR1=0x0,UxBR0=0x06,UxMCTL=0x6F---4800bit/s
- UMCTL0 = 0x6f ;//Modulation // UxBR1=0x0,UxBR0=x03,UxMCTL=0x4A---9600bit/s
- //************BAUD=2400Bit/s******************/
- UCTL0 &= ~SWRST ; // Initialize USART state machine
- IE1 |= URXIE0 ; //Open Transmit interrupt
- }
- /************************************************
- 定时器A中断服务程序把AD采集的数据放到
- results[Num_of_Results]
- ************************************************/
- #pragma vector=TIMERA0_VECTOR //TIMERA0_VECTOR INTERRUPT SERVICE
- __interrupt void TIMERAISR (void) //ROUTINE
- {
- _BIC_SR(LPM0_bits) ;
- temp = ADC12MEM0 ; //SAVE THE CONVERSATIN RESULT
- ADDataTodecimal(value,temp); //Conversation HEX into DECIMAL
- for(j = 0;j <= 3;j++)
- {
- value[j] += 0x30 ; //Conversation the DECIMAL into
- }
- SendDataToPC(value); //Transmit a serial of characters
- //for(uint k=0x7f;k>0;k--);
- } //per time
- #pragma vector = UART0RX_VECTOR
- __interrupt void receive_ISR(void)
- {
- _BIC_SR_IRQ(LPM3_bits); // Clear LPM3 bits from 0(SR)
- if ( RXBUF0 == 0x31 )
- {
- UCTL0 |= SWRST;
- ME1 &= ~UTXE0;
- UCTL0 &= ~SWRST;
- }
- if ( RXBUF0 == 0x32 )
- {
- UCTL0 |= SWRST;
- ME1 |= URXE0 + UTXE0 ; // Enable USART0 T/RXD
- UCTL0 &= ~SWRST;
- }
- }
- /***********************************
- 功能:发送数据给PC机
- 参数:*P指向被发送的数据的缓冲区
- 还回值:无
- 发送3位数据-----参考下面发送4位程序
- ***********************************/
- void SendDataToPC(uchar *value)
- {
- while(*value != '/0') //JUDGE A CHARACTER IS END SIGN OR NOT
- {
- while(!(IFG1 & UTXIFG0)) ;//TRANSMIT COMPLETELY OR NOT
- TXBUF0 = *value ;
- value++ ;
- }
- while(!(IFG1 & UTXIFG0)) ;
- TXBUF0 = '/n' ;
- }
- /*****************************/
- void SendDataToPC1(uchar value)
- {
- while(!(IFG1 & UTXIFG0)) ;
- TXBUF0 = value ;
- while(!(IFG1 & UTXIFG0)) ;
- TXBUF0 = '/n' ;
- }
- /********************************************
- 函数名称:ADDataTodecimal
- 功 能:将16进制ADC转换数据变换成十进制
- 表示形式
- 参 数:value--16进制数据
- p--指向存放转换结果的指针
- 返回值 :无
- ********************************************/
- void ADDataTodecimal(uchar *p,uint value)
- {
- p[0] = value / 1000 ; //THE THOUSAND BIT
- p[1] = (value - p[0]*1000)/100 ; //THE HUNDRED BIT
- p[2] = (value - p[0]*1000 - p[1]*100)/10 ; //THE DECIMAL BIT
- p[3] = (value - p[0]*1000 - p[1]*100 - p[2]*10);// THE INDIVIDUAL BIT
- }
- /*******************************
- 功能:延时
- **************************
- void delay_l(int q)
- {
- int a,b;
- for(a=0; a<q; a++ )
- for(b=0;b<30000;b++);
- }
- 上面的程序是MSP430F149的采用定时器定时触发A/D转换,并把转换好的数据发送到PC机,
- // FormComDlg.cpp : implementation file
- //
- #include "stdafx.h"
- #include "FormCom.h"
- #include "FormComDlg.h"
- #include "time.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /
- // CAboutDlg dialog used for App About
- //int data[4096];
- //#define Num 1000
- class CAboutDlg : public CDialog
- {
- public:
- CAboutDlg();
- // Dialog Data
- //{{AFX_DATA(CAboutDlg)
- enum { IDD = IDD_ABOUTBOX };
- //}}AFX_DATA
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(CAboutDlg)
- protected:
- virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
- //}}AFX_VIRTUAL
- // Implementation
- protected:
- //{{AFX_MSG(CAboutDlg)
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
- };
- CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
- {
- //{{AFX_DATA_INIT(CAboutDlg)
- //}}AFX_DATA_INIT
- }
- void CAboutDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CAboutDlg)
- //}}AFX_DATA_MAP
- }
- BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
- //{{AFX_MSG_MAP(CAboutDlg)
- // No message handlers
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /
- // CFormComDlg dialog
- CFormComDlg::CFormComDlg(CWnd* pParent /*=NULL*/)
- : CDialog(CFormComDlg::IDD, pParent)
- {
- //{{AFX_DATA_INIT(CFormComDlg)
- m_strReceiveData = _T("");
- m_selcom = _T("");
- m_selbaud = _T("");
- //}}AFX_DATA_INIT
- // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
- m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
- }
- void CFormComDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CFormComDlg)
- DDX_Control(pDX, IDC_COMBO3, m_sendControlInfo);
- DDX_Control(pDX, IDC_COMBO2, m_selbuadd);
- DDX_Control(pDX, IDC_COMBO1, m_selcomm);
- DDX_Control(pDX, IDC_EDIT2, m_ctrReceiveData);
- DDX_Control(pDX, IDC_MSCOMM1, m_ctrComm);
- DDX_Text(pDX, IDC_EDIT2, m_strReceiveData);
- DDX_CBString(pDX, IDC_COMBO1, m_selcom);
- DDX_CBString(pDX, IDC_COMBO2, m_selbaud);
- //}}AFX_DATA_MAP
- }
- BEGIN_MESSAGE_MAP(CFormComDlg, CDialog)
- //{{AFX_MSG_MAP(CFormComDlg)
- ON_WM_SYSCOMMAND()
- ON_WM_PAINT()
- ON_WM_QUERYDRAGICON()
- ON_BN_CLICKED(IDC_BUTTON1_CLEARRECE, OnClearReceiveData)
- ON_WM_TIMER()
- ON_BN_CLICKED(IDC_SendData, OnSendData)
- ON_BN_CLICKED(IDC_BUTTON1, On_CloseSerial)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /
- // CFormComDlg message handlers
- BOOL CFormComDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
- // Add "About..." menu item to system menu.
- // IDM_ABOUTBOX must be in the system command range.
- ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
- ASSERT(IDM_ABOUTBOX < 0xF000);
- CMenu* pSysMenu = GetSystemMenu(FALSE);
- if (pSysMenu != NULL)
- {
- CString strAboutMenu;
- strAboutMenu.LoadString(IDS_ABOUTBOX);
- if (!strAboutMenu.IsEmpty())
- {
- pSysMenu->AppendMenu(MF_SEPARATOR);
- pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
- }
- }
- // Set the icon for this dialog. The framework does this automatically
- // when the application's main window is not a dialog
- SetIcon(m_hIcon, TRUE); // Set big icon
- SetIcon(m_hIcon, FALSE); // Set small icon
- // TODO: Add extra initialization here
- for(int i=0;i<ECGNum;i++)ECGdata[i]=0;
- ecgnum=0;
- // if (m_selcomm.GetCurSel()<0)
- // i = 2;
- // else
- // i = m_selcomm.GetCurSel()+1;
- m_ctrComm.SetCommPort(2);//选择端口COM2
- // if (m_selbuadd.GetCurSel()<0)
- // i = 2;
- // else
- /// i = m_selbuadd.GetCurSel();
- //int n=m_selbuadd.GetLBTextLen(i);
- // CString str;
- // m_selbuadd.GetLBText(i,str);
- // str += ",n,8,1";
- m_ctrComm.SetInputMode(1);//输入方式为二进制
- m_ctrComm.SetInBufferSize(4096);//设置输入缓冲区大小
- m_ctrComm.SetOutBufferSize(512);//设置输出缓冲区大小
- m_ctrComm.SetSettings("4800,n,8,1");//设置串口4800,N,8,1
- if(!m_ctrComm.GetPortOpen())//检测串口是否打开
- m_ctrComm.SetPortOpen(true);//打开串口
- m_ctrComm.SetRThreshold(1);//参数1表示当串口接收缓冲区中有多于1或者等于1个
- //字符将引发一个接收数据的OnCom事件
- m_ctrComm.SetInputLen(0);//设置当前接收数据的长度为0
- m_ctrComm.GetInput();//先预留缓冲区以清除残留数据
- return TRUE; // return TRUE unless you set the focus to a control
- }
- void CFormComDlg::OnSysCommand(UINT nID, LPARAM lParam)
- {
- if ((nID & 0xFFF0) == IDM_ABOUTBOX)
- {
- CAboutDlg dlgAbout;
- dlgAbout.DoModal();
- }
- else
- {
- CDialog::OnSysCommand(nID, lParam);
- }
- }
- // If you add a minimize button to your dialog, you will need the code below
- // to draw the icon. For MFC applications using the document/view model,
- // this is automatically done for you by the framework.
- void CFormComDlg::OnPaint()
- {
- if (IsIconic())
- {
- CPaintDC dc(this); // device context for painting
- SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
- // Center icon in client rectangle
- int cxIcon = GetSystemMetrics(SM_CXICON);
- int cyIcon = GetSystemMetrics(SM_CYICON);
- CRect rect;
- GetClientRect(&rect);
- int x = (rect.Width() - cxIcon + 1) / 2;
- int y = (rect.Height() - cyIcon + 1) / 2;
- // Draw the icon
- dc.DrawIcon(x, y, m_hIcon);
- }
- else
- {
- CDialog::OnPaint();
- }
- }
- // The system calls this to obtain the cursor to display while the user drags
- // the minimized window.
- HCURSOR CFormComDlg::OnQueryDragIcon()
- {
- return (HCURSOR) m_hIcon;
- }
- BEGIN_EVENTSINK_MAP(CFormComDlg, CDialog)
- //{{AFX_EVENTSINK_MAP(CFormComDlg)
- ON_EVENT(CFormComDlg, IDC_MSCOMM1, 1 /* OnComm */, OnComm, VTS_NONE)
- //}}AFX_EVENTSINK_MAP
- END_EVENTSINK_MAP()
- /************************************************************************/
- void CFormComDlg::OnComm()
- {
- //SetTimer(1,100,NULL);
- LONG len=0,k=0;//定义从串口发送过来是数据长度
- BYTE rxdata[1200];//定义一个存放从串口发送数据的BYTE类型的数组
- CString strtemp=_T("0");//定义CString类型的变量实现BYTE类型转换为CString类型
- // TODO: Add your control notification handler code here
- COleVariant variant_inp;
- COleSafeArray safearray_inp;//定义一个COleSafeArray的类型的变量实现串口数据类型与
- if(m_ctrComm.GetCommEvent()==2)//判断串口接收缓冲区有没接收到数据
- {
- variant_inp.Attach(m_ctrComm.GetInput());//把串口缓冲区的数据读到variant_inp结构体中
- safearray_inp=variant_inp;
- len=safearray_inp.GetOneDimSize();
- BOOL flag;
- for(k=0;k<len;k++)
- safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE数组
- for(k=0;k<len;k++)//把BYTE的数组转换为CString
- {
- BYTE bt=*(char*)(rxdata+k);
- strtemp.Format("%c",bt);
- m_strReceiveData+=strtemp;//m_strReceiveData用来存储串口接收的所有数据
- flag =true;
- while(flag)//判断从串口接收的数据是否大于等于5个字节,如果满足这个条件
- {
- if(m_strReceiveData.GetLength()<5)
- flag = false;
- else
- {
- strtemp=m_strReceiveData.Left(4);//取conv字符串中的最左边四个字符,因为我发送过来的数据是5个字节,
- //其中最后一个字节是一个‘/n
- data[ecgnum]=_ttoi(strtemp);//两种数据的转换
- num=(ecgnum+1)%ECGNum;//数组长度加1
- m_strReceiveData.Delete(1,5);//删除已经转换的字符串
- OnTimer(1);
- }
- }
- strtemp=_T("0");//重新给这个变量进行初始化
- }
- }
- UpdateData(false);
- }
- void CFormComDlg::OnClearReceiveData()
- {
- // TODO: Add your control notification handler code here
- m_strReceiveData.Empty();//CLEAR THE CONTENT OF m_strReceiveData
- for (int i = 0;i<=num-1;i++);
- data[i] = 0;
- num = 0;
- UpdateData(false);//UPDATE THE DRAWING AREA,In principle the aim of this item
- }
- void CFormComDlg::DrawECG(CDC* pDC)
- {
- int i=0;
- CRect rec;
- CWnd* pWnd=GetDlgItem(IDC_STATIC12);//DIRECT TO DRAWING CONTROL
- pWnd->GetClientRect(&rec);//DIRECT TO THE CLIENT PICTURE AREA
- pDC->Rectangle(&rec);//DIRECTED THE PICTURE AREA
- CPen* pPenRed = new CPen;//RED PEN
- pPenRed->CreatePen(PS_SOLID,1,RGB(255,0, 0));
- CPen* pOldPen=pDC->SelectObject(pPenRed);
- int temp = 0;
- for(i=0;i<num-1;i++)//pay attention to the consistent with coordinate between two point
- {
- pDC->MoveTo(rec.left+temp,data[i]/10-30);
- pDC->LineTo(rec.left+1+temp,data[i+1]/10-30);
- if(rec.left+1+temp>rec.Width()-10)
- {
- temp = 0;
- }
- else
- temp = temp + 1;
- }
- pDC->SelectObject(pOldPen);
- pWnd->ReleaseDC(pDC);
- delete pPenRed;
- }
- /**********************************************************
- /**********************************************************/
- void CFormComDlg::OnTimer(UINT nIDEvent)
- {
- // TODO: Add your message handler code here and/or call default
- CRect rect;
- CWnd* pWnd = GetDlgItem(IDC_STATIC12);
- pWnd->GetClientRect(&rect);
- CDC* pDC = pWnd->GetDC();
- pWnd->Invalidate();
- pWnd->UpdateWindow();
- CBitmap memBitmap;
- CBitmap* pOldBmp = NULL;
- memDC.CreateCompatibleDC(pDC);
- memBitmap.CreateCompatibleBitmap(pDC,rect.right,rect.bottom);
- pOldBmp = memDC.SelectObject(&memBitmap);
- memDC.BitBlt(rect.left,rect.top,rect.right,rect.bottom,pDC,0,0,SRCCOPY);
- DrawECG(&memDC);
- pDC->BitBlt(rect.left,rect.top,rect.right,rect.bottom,&memDC,0,0,SRCCOPY);
- memDC.SelectObject(pOldBmp);
- memDC.DeleteDC();
- memBitmap.DeleteObject();
- pWnd->ReleaseDC(pDC);
- CDialog::OnTimer(nIDEvent);
- }
- void CFormComDlg::OnSendData()
- {
- // TODO: Add your control notification handler code here
- CString s;
- int i;
- if (m_sendControlInfo.GetCurSel()<0)
- i=m_sendControlInfo.SetCurSel(1);
- else
- i = m_sendControlInfo.GetCurSel();
- m_sendControlInfo.GetLBText(i,s);
- m_ctrComm.SetOutput(COleVariant(s));
- }
- void CFormComDlg::On_CloseSerial()
- {
- // TODO: Add your control notification handler code here
- if (m_ctrComm.GetPortOpen())
- {
- m_ctrComm.SetPortOpen(false);
- }
- else
- {
- m_ctrComm.SetPortOpen(true);
- }
- }
- 上面是MFC中的一部分程序
PC机可以正常的接收来自MSP430F149发送过来的数据,问题是,当我在关闭上位机的串口,然后重新打开串口接收时,就会出现乱码,有时是重新打开又可以正常接收;不过大多数还是显示乱码;
另外 PC机在正常接收时,当我点击COM选择组合框时,组合框的内容不停的闪烁,点击buadrate组合框时,也会不停的闪烁;不知道是什么问题?
本打算在上位机上发送 1 和 2来通知 MSP430F149关闭和打开串口结果是 发送1让MSP430F149停止发送可以实现,
1: PC机发送1给MSP430 通知MSP430关闭串口;
2:PC机发送2 给MSP430 通知MSP430打开串口,进行通信;
当发送2时,让MSP430F149重新打开串口,进行通信时就不能实现,请问各路高手 这到底是什么问题?
PC机程序如下
- void CFormComDlg::OnSendData()
- {
- // TODO: Add your control notification handler code here
- CString s;
- int i;
- i = m_sendControlInfo.GetCurSel();
- m_sendControlInfo.GetLBText(i,s);
- m_ctrComm.SetOutput(COleVariant(s));
- }
MSP430F149的对应的程序如下
- #pragma vector = UART0RX_VECTOR
- __interrupt void receive_ISR(void)
- {
- _BIC_SR_IRQ(LPM3_bits);
- if ( RXBUF0 == 0x31 )
- {
- UCTL0 |= SWRST;
- ME1 &= ~UTXE0; //关闭串口发送功能
- UCTL0 &= ~SWRST;
- }
- if ( RXBUF0 == 0x32 )
- {
- UCTL0 |= SWRST;
- ME1 |= URXE0 + UTXE0 ; // Enable USART0 T/RXD
- UCTL0 &= ~SWRST;
- }
- }
发现采用上面的办法 不能实现串口的关和闭,又采用用MS COMM控件来实现串口的关和闭 ,在正常情况下MSP430发送数据给PC机,PC机可以正常接收,当按下CloseSerial来关闭串口时,然后过会儿重新按下CloseSerial按钮 进行重新接收MSP430发送过来的数据时,就会出现乱码,请问高手用什么办法可以解决这个问题?PC机的程序如下
- void CFormComDlg::On_CloseSerial()
- {
- // TODO: Add your control notification handler code here
- if (m_ctrComm.GetPortOpen())
- {
- m_ctrComm.SetPortOpen(false);
- }
- else
- {
- m_ctrComm.SetPortOpen(true);
- }
- }
我的联系QQ 258130629
小弟 在此先谢谢各位高手啦!