亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? drv_i2c.c

?? picos18的i2c驅(qū)動程序樣例
?? C
字號:
/**********************************************************************/
/*                                                                    */
/* File name: drv_i2c.c                                               */
/*                                                                    */
/* Since:     2004-Aug-10                                             */
/*                                                                    */
/* Version:   PICos18 v2.00                                           */
/*            Copyright (C) 2003, 2004 Pragmatec.                     */
/*            I2C driver v1.04                                        */
/*                                                                    */
/* Author:    DEVINE, Dan [DD] (ddevine@nwi-online.com) 			  */
/*			  ROZIER Bertrand [RZR] bertrand.rozier@pragmatec.net     */
/*																	  */
/* Purpose:   I2C communications task, allowing other client          */
/*            tasks to share operation of the PIC18 MSSP module.      */
/*                                                                    */
/* Distribution: This file is part of PICos18.                        */
/*            PICos18 is free software; you can redistribute it       */
/*            and/or modify it under the terms of the GNU General     */
/*            Public License as published by the Free Software        */
/*            Foundation; either version 2, or (at your option)       */
/*            any later version.                                      */
/*                                                                    */
/*            PICos18 is distributed in the hope that it will be      */
/*            useful, but WITHOUT ANY WARRANTY; without even the      */
/*            implied warranty of MERCHANTABILITY or FITNESS FOR A    */
/*            PARTICULAR PURPOSE.  See the GNU General Public         */
/*            License for more details.                               */
/*                                                                    */
/*            You should have received a copy of the GNU General      */
/*            Public License along with gpsim; see the file           */
/*            COPYING.txt. If not, write to the Free Software         */
/*            Foundation, 59 Temple Place - Suite 330,                */
/*            Boston, MA 02111-1307, USA.                             */
/*                                                                    */
/*          > A special exception to the GPL can be applied should    */
/*            you wish to distribute a combined work that includes    */
/*            PICos18, without being obliged to provide the source    */
/*            code for any proprietary components.                    */
/*                                                                    */
/* History:                                                           */
/*   2004/09/10  [DD]  Create this file.                              */
/*	 2004/11/23	 [RZR] Update for PICos18 V2 & Add TimeOut			  */
/*	 2004/11/23	 [XM]  Added Suspend(Resume)OSInterrupts() calls in   */
/*                     I2C_deqMsg function.                           */
/*                                                                    */
/**********************************************************************/


#include "drv_i2c.h"


/**********************************************************************
 *      Forward declarations of local functions not for public
 *
 *********************************************************************/
#define I2C_TIMEOUT_ALARM	3

I2C_message_tRef	I2C_deqMsg(void); 

I2C_message_tRef	I2C_list_head;		//	Start of message queue
I2C_message_tRef	I2C_current_message;//	Current message

unsigned char		I2C_list_count;		//	Number of items currently in queue
unsigned char 		I2C_bus_state;		//	Current/next I2C state/action

unsigned char		*p_data;			//	Pointer into message data
unsigned char		I2C_byte_count;		//	Counts from 0 to 
										//	current_message.num_bytes


/**********************************************************************
 *
 *							I2C DRIVER
 *
 *********************************************************************/
TASK(I2C_Drv)
{
	EventMaskType  Mask_event;
	
	// Set up the I2C port
	TRISC |= 0b00011000;
	
	PIE1  |= 0b00001000;
	PIE2  |= 0b00001000;
	
	SSPCON1 = 0b00101000;
	SSPADD= 0x63;           // Assuming 40MHz speed - 100KHz
	//SSPADD= 0x27;         // Assuming 16MHz speed - 100KHz
	//SSPADD  = 0x09;       // Assuming 04MHz speed - 100KHz
	SSPSTAT = 0b10000000;   // 100Khz
	PIR2bits.BCLIF = 0;
	
	// Initialize Task/module variables
	I2C_list_count = 0;
	I2C_list_head  = NULL;
	
	//	Initiate a stop condition to clear bus
	I2C_bus_state   = BUS_STOP;
	SSPCON2bits.PEN = 1;

	while (1)	
	{	// Wait for another task to post 1 or more messages to send
		WaitEvent(I2C_NEW_MSG);
		ClearEvent(0xFF); //Clear all Event

		while (I2C_list_count > 0)
		{
			I2C_current_message = I2C_deqMsg();
			I2C_byte_count = I2C_current_message->num_bytes;
			p_data = I2C_current_message->ram_data;
			// Specific settings for SMBus
			if (I2C_current_message->flags.SMBus == 1)
			{
				// Enable SMBus specific inputs
				SSPSTATbits.CKE = 1; 
			}
			else
			{
				// Disble SMBus specific inputs
				SSPSTATbits.CKE = 0;
			}
			// Set the timeout at 10ms
			CancelAlarm(I2C_TIMEOUT_ALARM);
			SetRelAlarm(I2C_TIMEOUT_ALARM, 10, 0);
			// Start I2C transfert
			I2C_bus_state = BUS_START;
			SSPCON2bits.SEN = 1;
			// Wait for transfert result
			WaitEvent(TIMEOUT_EVENT | BUSERROR_EVENT | IDLE_EVENT);
			GetEvent(I2C_DRV_ID, &Mask_event);
			// Timeout occured (10 ms)
			if (Mask_event & TIMEOUT_EVENT)
    		{
				ClearEvent(TIMEOUT_EVENT);
				I2C_current_message->error = ERR_I2C_TIMEOUT;
				I2C_current_message->flags.busy = 0;
				I2C_current_message->flags.error = 1;
				SetEvent(I2C_current_message->CallerID,I2C_QUEUE_EMPTY);
			}
			// BUS ERROR occured
			if (Mask_event & BUSERROR_EVENT)
    		{
				ClearEvent(BUSERROR_EVENT);
				// If the automatic retry is used
				if (I2C_current_message->retry_counter != 0)
				{
					I2C_current_message->retry_counter--;
					I2C_current_message->flags.busy = 1;
					I2C_enqMsg(I2C_current_message);
				}
				else 
				{
					I2C_current_message->flags.busy = 0;
					I2C_current_message->flags.error = 1;
					SetEvent(I2C_current_message->CallerID,I2C_QUEUE_EMPTY);
				}
			}
			if (Mask_event & IDLE_EVENT)
   			{
				// Message sent successfully
				ClearEvent(IDLE_EVENT);
				// Disabled TIMEOUT counter
				CancelAlarm(I2C_TIMEOUT_ALARM);
				SetEvent(I2C_current_message->CallerID,I2C_QUEUE_EMPTY);
			}
		}// End of list_count_loop				
	} // End of the infinte loop
}// End of task
 

/**********************************************************************
 *
 *	Enqueue a client packet object into the I2C task queue.
 *
 *	Once placed in queue, client must not modify the data
 *	otherwise unpredictable results. To safely change the object,
 *	dequeue, modify, re-enqueue.
 *
 *	Returns 1 if successfull, 0 if message could not be enqueued
 **********************************************************************/
unsigned char I2C_enqMsg(I2C_message_tRef toEnqueue)
{
  I2C_message_tRef I2C_list_itor;

  if (toEnqueue != NULL)
  {
    SuspendOSInterrupts();
    if (I2C_list_head == NULL)
      I2C_list_head = toEnqueue;
    else
    {
      I2C_list_itor = I2C_list_head;
      while (I2C_list_itor->next != NULL)
        I2C_list_itor = I2C_list_itor->next;
      I2C_list_itor->next = toEnqueue;
    }
    toEnqueue->next     = NULL;
    toEnqueue->CallerID = id_tsk_run;
    I2C_list_count++;
    ResumeOSInterrupts();
    return 1;
  }
  else
    return 0;
}

/**********************************************************************
 *
 *	Dequeue a client message from the I2c task queue.
 *
 *
 *********************************************************************/
I2C_message_tRef I2C_deqMsg(void)
{
  I2C_message_tRef I2C_list_itor;

  SuspendOSInterrupts();
  I2C_list_itor = NULL;
  if (I2C_list_head != NULL)
  {
    I2C_list_itor = I2C_list_head;
    I2C_list_head = I2C_list_head->next;
    I2C_list_count--;
  }
  ResumeOSInterrupts();
  SetEvent(I2C_DRV_ID, I2C_NEW_MSG);
  return I2C_list_itor;
} 


/**********************************************************************
 *
 *			I2C Interrupt Service Routine
 * 
 *			Operates as state machine with case statements
 *			while interrupt handler is large as whole, only
 *			small ammount of code should be executed at any
 *			one time
 *
 *			The I2C_bus_state when entering the switch statement relates
 *			to what event was called for prior to the interrupt occuring.
 *			example:set I2C_bus_state to "stop", enable stop bit and wait
 *			for interrupt to return here in (hopefully) stopped condition
 *			after completion of the event.
 *		
 **********************************************************************/
void I2C_INT (void)
{
  PIR1bits.SSPIF = 0;
  switch (I2C_bus_state)
	{
	    // Received interrupt after calling start event
		case (BUS_START): 
		{
			// Got control of bus ?
			if (SSPSTATbits.S) 
			{	// Launch into sending next byte
				SSPSTATbits.S = 0;
				SSPBUF = I2C_current_message->control & 0xFE;
				I2C_bus_state = BUS_CTRL_WRITE;
			}
					
			if (PIR2bits.BCLIF)		//	Failed on bus collision
			{	// FIXME:  Find a better way to keep looping while waiting for
				// the bus to become idle.  Calling for another start will occur
				// according to period TbaudRateGenerator...could have lots of frequent
				// interrupts until bus is clear.
				SSPCON2bits.SEN = 1;
				SetEvent(I2C_DRV_ID,BUSERROR_EVENT);
			}					
			break;
		}
			
				
		// Received interrupt after control write
		case (BUS_CTRL_WRITE):
				{
					// Slave is answered
					if (!SSPCON2bits.ACKSTAT)
					{
						if (I2C_current_message->flags.long_addr == 1)
						{
							SSPBUF = I2C_current_message->addr_high;
							I2C_bus_state = BUS_WRITE_ADDR_H;
						}
						else
						{
							SSPBUF = I2C_current_message->addr_low;
							I2C_bus_state = BUS_WRITE_ADDR_L;
						}
					}
					// Slave not responding
					else if (SSPCON2bits.ACKSTAT)
					{
						I2C_current_message->error = ERR_I2C_NOSLAVE;
						I2C_bus_state = BUS_IDLE;
						SetEvent(I2C_DRV_ID,BUSERROR_EVENT);
					}
				break;
				}

				
		// Received interrupt after send high addr
		case (BUS_WRITE_ADDR_H):
				{
					// Slave ACK'd
					if (!SSPCON2bits.ACKSTAT)
					{
						SSPBUF = I2C_current_message->addr_low;
						I2C_bus_state = BUS_WRITE_ADDR_L;
					}
					else
					{
						I2C_bus_state = BUS_IDLE;
						I2C_current_message->error = ERR_I2C_NACK_ADDR;
						SetEvent(I2C_DRV_ID,BUSERROR_EVENT);
					}					
					break;
				}


		// Received interrupt after send low addr
		case (BUS_WRITE_ADDR_L):
				{
					// Slave responded
					if (!SSPCON2bits.ACKSTAT)
					{
						if (I2C_current_message->control & 0x01)
						{	//	This is a read, initiate a restart condition
							I2C_bus_state = BUS_RESTART;
							SSPCON2bits.RSEN = 1;
						}					
						else
						{	//	Next operation is a data write, output first byte
							I2C_bus_state = BUS_WRITE_DATA;
							SSPBUF = *p_data;
							p_data++;
							I2C_byte_count--;
						}
					}
					// Slave did not respond
					else
					{
							I2C_bus_state = BUS_IDLE;
							I2C_current_message->error = ERR_I2C_NACK_ADDR;
							SetEvent(I2C_DRV_ID,BUSERROR_EVENT);
					}
					break;
				}



			
		// Received interrupt after calling for restart
		case (BUS_RESTART):
				{
					SSPBUF = I2C_current_message->control;						
					I2C_bus_state = BUS_CTRL_READ;
					break;
				}


					
		// Received interrupt after calling for control read
		case (BUS_CTRL_READ):
				{
					// Slave responded
					if (!SSPCON2bits.ACKSTAT)
					{
						SSPCON2bits.RCEN = 1;
						I2C_bus_state = BUS_READ_DATA;
					}
					else
					{
						I2C_bus_state = BUS_IDLE;
						SetEvent(I2C_DRV_ID,BUSERROR_EVENT);
					}
					break;
				}


		// Received interrupt after setting RCEN
		case (BUS_READ_DATA):
				{
					*p_data = SSPBUF;
					p_data++;
					I2C_byte_count--;
					
					if (I2C_byte_count == 0)
						SSPCON2bits.ACKDT = 1;
					else
						SSPCON2bits.ACKDT = 0;
						
					I2C_bus_state = BUS_SEND_ACK_NACK;       
		  	 		SSPCON2bits.ACKEN = 1;
					break;
				}
		
		
		// Received interrupt after setting/clearing ACKDT 
		case (BUS_SEND_ACK_NACK):
				{
					if (SSPCON2bits.ACKDT)
					{	// Last was nack, so we're done..
						SSPCON2bits.ACKDT = 0;
						I2C_bus_state = BUS_STOP;
						SSPCON2bits.PEN = 1;
					}
					else
					{	//	Last was ack, so there must be more to transfer 
						SSPCON2bits.RCEN = 1;
						I2C_bus_state = BUS_READ_DATA;
					}
					break;
				}

		
		// Received interrupt after calling for stop
		case (BUS_STOP):
				{
					PIR2bits.BCLIF = 0;
					I2C_bus_state = BUS_IDLE;
					SetEvent(I2C_DRV_ID,IDLE_EVENT);
					break;
				}				
						
		case (BUS_WRITE_DATA):
				{
					//	Check ACKSTAT to determine if slave answered
					if (SSPCON2bits.ACKSTAT)
					{
						I2C_current_message->error = ERR_I2C_NACK_DATA;
						I2C_bus_state = BUS_STOP;
						break;
					}
			
					//	Write a byte of data to the slave
					//	Decide which state is next
					if (I2C_byte_count > 0)
					{
						SSPBUF = *p_data;
						p_data++;
						I2C_byte_count--;
						I2C_bus_state = BUS_WRITE_DATA;
					}
					else
					{
						SSPCON2bits.PEN = 1;
						I2C_bus_state = BUS_STOP;
						I2C_current_message->error = ERR_I2C_SUCCESS;
					}
					break;
				}
						
			default:
					break;
	}	//	End switch
  return;
}


/* End of File : drv_i2c.c  */

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产欧美一区二区精品婷婷| 综合久久给合久久狠狠狠97色| 岛国一区二区在线观看| 亚洲一区二区不卡免费| 欧美激情一区二区三区| 欧美一级精品大片| 在线中文字幕一区二区| 国产夫妻精品视频| 理论片日本一区| 亚洲va国产va欧美va观看| 亚洲欧洲美洲综合色网| 久久综合九色欧美综合狠狠| 欧美女孩性生活视频| 色丁香久综合在线久综合在线观看| 国产伦精一区二区三区| 日韩avvvv在线播放| 一区二区三区在线高清| 国产精品久久久久久福利一牛影视 | 国产一区二区福利| 亚洲一二三四区| 中文字幕日韩欧美一区二区三区| 久久青草国产手机看片福利盒子 | 亚洲图片有声小说| 亚洲天堂2014| 国产精品成人一区二区艾草| 久久精品视频免费观看| 久久亚洲捆绑美女| 国产精品传媒视频| 夜夜嗨av一区二区三区| 欧美日韩小视频| 欧美吞精做爰啪啪高潮| 99国产欧美久久久精品| 成a人片亚洲日本久久| 国产成人日日夜夜| 国产精品系列在线播放| 国产乱国产乱300精品| 国产美女精品在线| 风流少妇一区二区| 国产成人av电影在线观看| 国产成人三级在线观看| 国产91精品入口| 99国内精品久久| 欧美亚日韩国产aⅴ精品中极品| 欧美视频第二页| 在线播放91灌醉迷j高跟美女 | 综合激情成人伊人| 国产精品卡一卡二卡三| 国产精品久久久久一区| 亚洲欧洲精品一区二区三区不卡 | **性色生活片久久毛片| 亚洲欧美日韩综合aⅴ视频| 亚洲欧美视频在线观看| 一区二区欧美在线观看| 午夜激情综合网| 美女尤物国产一区| 国产高清成人在线| 99国产精品久久久久久久久久 | 久久久久久免费毛片精品| 亚洲国产精品成人综合| 亚洲婷婷在线视频| 亚洲福利一区二区| 国内成人免费视频| 成人99免费视频| 欧美性猛片aaaaaaa做受| 91精品国产欧美一区二区成人 | 色琪琪一区二区三区亚洲区| 欧美高清视频一二三区| 精品久久国产老人久久综合| 中文字幕在线不卡视频| 亚洲国产精品久久人人爱蜜臀| 久久99国产精品麻豆| 成人午夜精品在线| 欧美美女激情18p| 国产亚洲一区二区三区四区| 亚洲图片你懂的| 日韩av网站在线观看| 成人黄页在线观看| 欧美精品xxxxbbbb| 国产欧美日韩另类一区| 亚洲成人在线免费| 国产美女精品人人做人人爽| 色天使久久综合网天天| 久久久久久久久久久99999| 亚洲欧美日韩在线| 狠狠色伊人亚洲综合成人| 91福利国产成人精品照片| 久久亚洲一区二区三区明星换脸 | 国产一区二三区| 在线欧美一区二区| 久久久99精品免费观看不卡| 亚洲午夜电影在线| 不卡的电视剧免费网站有什么| 在线电影国产精品| 亚洲女女做受ⅹxx高潮| 国产在线一区观看| 欧美日产国产精品| 日韩理论片中文av| 国产成人自拍在线| 91精品国产乱| 亚洲午夜一区二区| 色综合天天视频在线观看| 26uuu色噜噜精品一区二区| 亚洲国产另类精品专区| youjizz久久| 久久精品无码一区二区三区| 视频一区欧美精品| 色综合天天综合网国产成人综合天 | 日产精品久久久久久久性色| 97久久精品人人做人人爽| 精品国产伦一区二区三区免费| 亚洲第一激情av| 色琪琪一区二区三区亚洲区| 国产精品麻豆99久久久久久| 国产综合色视频| 日韩一区二区在线看| 亚洲国产成人va在线观看天堂| 91网页版在线| 国产精品乱人伦中文| 国产高清在线观看免费不卡| 日韩精品在线一区二区| 水野朝阳av一区二区三区| 色老汉一区二区三区| 亚洲免费三区一区二区| 91啪九色porn原创视频在线观看| 国产欧美日韩精品一区| 懂色av噜噜一区二区三区av| 久久精品一区八戒影视| 国产成人久久精品77777最新版本| 精品日韩欧美一区二区| 久久97超碰色| 久久综合九色综合欧美亚洲| 国产一区二区三区在线观看免费视频| 91精品国产综合久久精品| 午夜精品久久久久久久99水蜜桃 | 欧美电影一区二区| 日韩av一区二区三区四区| 欧美精品色综合| 日本va欧美va瓶| 精品三级在线观看| 国产精品456| 中文字幕一区二区三区蜜月| 色婷婷综合久色| 午夜亚洲国产au精品一区二区| 欧美美女一区二区在线观看| 老汉av免费一区二区三区| www国产亚洲精品久久麻豆| 国产成人亚洲综合a∨猫咪| 国产精品视频免费| 色婷婷综合久久久| 亚洲成av人**亚洲成av**| 欧美一二三在线| 国产高清一区日本| 亚洲欧美日韩久久| 欧美剧情片在线观看| 国内精品嫩模私拍在线| 中文在线一区二区| 在线国产亚洲欧美| 久久国产生活片100| 久久精品欧美一区二区三区麻豆| 成人黄色综合网站| 五月天激情综合网| 欧美zozozo| 99精品视频中文字幕| 亚洲国产精品自拍| 久久一区二区三区四区| 一本久久a久久精品亚洲| 蜜桃传媒麻豆第一区在线观看| 久久色在线视频| 在线日韩av片| 国产精品白丝av| 亚洲综合自拍偷拍| 精品国产精品网麻豆系列| 一本久久综合亚洲鲁鲁五月天| 日本大胆欧美人术艺术动态| 国产欧美日韩视频在线观看| 欧美日韩卡一卡二| 国产xxx精品视频大全| 亚洲成人自拍一区| 国产嫩草影院久久久久| 欧美日韩精品专区| 成人免费视频caoporn| 日韩精品福利网| 国产精品的网站| 欧美不卡一区二区| 色悠悠久久综合| 国产99精品在线观看| 热久久国产精品| 亚洲免费看黄网站| 久久噜噜亚洲综合| 欧美日韩激情在线| 97久久精品人人做人人爽| 久久国内精品自在自线400部| 亚洲综合偷拍欧美一区色| 久久久一区二区三区捆绑**| 欧美乱熟臀69xxxxxx| 色噜噜久久综合| 国产不卡在线一区| 国产在线视频一区二区三区| 亚欧色一区w666天堂| 中文字幕在线观看不卡视频|